@Simon-Sun
2025-04-11T14:25:38.000000Z
字数 14801
阅读 117
学术
#include <iostream>#define int long longusing namespace std ;const int maxn = 2e5 + 7 ;int root , n , m , cnt , p , nxt ;struct node{int l , r , max , L , R ;} tr[maxn * 2 ] ;void insert(int &p , int now , int l , int r , int val ){if( !p){p = ++cnt ;tr[p].L = l , tr[p].R = r ;}if(l == r ){tr[p].max = val ;return ;}int mid = l + r >> 1 ;if(now <= mid ) insert(tr[p].l , now , l , mid , val ) ;else insert(tr[p].r , now , mid + 1 , r , val ) ;tr[p].max = max(tr[tr[p].l].max , tr[tr[p].r].max ) ;//cout << tr[p].max << ' ' ;}int query(int &p , int l , int r ){//cout<<l<<' '<<r<<endl;int ans = -maxn ;if(!p) return -1 ;//if( >= l && ) return tr[p].max ;int L = tr[p].L , R = tr[p].R ;//if(l == r ) return tr[p].max ;if(L == l && R == r) return tr[p].max ;// if(L >= l && r >= R ) return tr[p].max ;int mid = L + R >> 1 ;if(r <= mid ) ans = max(ans , query(tr[p].l , l , r) ) ;else if(l > mid ) ans = max(ans , query(tr[p].r , l , r )) ;else{if(l <= mid ) ans = max(ans , query(tr[p].l , l , mid )) ;if(r > mid ) ans = max(ans , query(tr[p].r , mid + 1 , r )) ;}// cout << ans << '\n' ;return ans ;}signed main(){cin >> m >> p ;while( m-- ){int x ;char op ; cin >> op >> x ;if(op == 'Q') nxt = query(root , n - x + 1 , n ) ,cout << nxt << '\n' ;else{insert(root , ++n , 1 , 200005 , ((x + nxt) % p + p ) % p) ;//cout << ((x + nxt) % p + p ) % p<< ' ' << nxt << '\n' ;}}}
//非动态开点#include <bits/stdc++.h>#define ll long long#define maxn 1010101#define ls p<<1#define rs p<<1|1using namespace std;ll a[maxn],n,m;struct node{ll L,R;ll add,sum;ll len(){return R-L+1;}}tree[maxn*3];void Up(ll p){tree[p].sum=tree[ls].sum+tree[rs].sum;}void build(ll l,ll r,ll p){tree[p].L=l; tree[p].R=r;if(l==r){tree[p].add=0;tree[p].sum=a[l];//区间是个点直接赋值即可return ;}ll mid=l+r>>1;build(l,mid,ls); build(mid+1,r,rs);Up(p);}void down(ll p){ll &t=tree[p].add;if(t==0)//如果没有标记,就不用下传return ;tree[ls].add+=t; tree[rs].add+=t;tree[ls].sum+=tree[ls].len()*t; tree[rs].sum+=tree[rs].len()*t;t=0;//清空标记}void update(ll l,ll r,ll a,ll p){if(tree[p].L==l&&tree[p].R==r){tree[p].add+=a;tree[p].sum+=(r-l+1)*a;return ;}ll mid=(tree[p].L+tree[p].R)>>1;down(p);//由于要修改下面的区间的值了,所以先把未下传的标记下传if(r<=mid)update(l,r,a,ls);else if(l>mid)update(l,r,a,rs);else{update(l,mid,a,ls);update(mid+1,r,a,rs);}Up(p);//向上合并一下}ll query(ll l,ll r,ll p){if(l==tree[p].L&&r==tree[p].R)return tree[p].sum;down(p);ll mid=tree[p].L+tree[p].R>>1;if(r<=mid)return query(l,r,ls);if(l>mid)return query(l,r,rs);else{return query(l,mid,ls)+query(mid+1,r,rs);//原因见配套notepad}}int main(){cin>>n>>m;for(ll i=1;i<=n;i++)cin>>a[i];build(1,n,1);while(m--){char op ;cin>>op;if(op == 'C'){ll x,y,t;cin>>x>>y>>t;update(x,y,t,1);}else{ll x,y;cin>>x>>y;cout<<query(x,y,1)<<endl;}}return 0;}
//牛客王老师版本#include <bits/stdc++.h>#define ll long long#define maxn 1010101#define ls p<<1#define rs p<<1|1using namespace std;ll a[maxn],n,m;struct node{ll L,R;ll add,sum;ll len(){return R-L+1;}}tree[maxn*3];void Up(ll p){tree[p].sum=tree[ls].sum+tree[rs].sum;}void build(ll l,ll r,ll p){tree[p].L=l; tree[p].R=r;if(l==r){tree[p].add=0;tree[p].sum=a[l];//区间是个点直接赋值即可return ;}ll mid=l+r>>1;build(l,mid,ls); build(mid+1,r,rs);Up(p);}void down(ll p){ll &t=tree[p].add;if(t==0)//如果没有标记,就不用下传return ;tree[ls].add+=t; tree[rs].add+=t;tree[ls].sum+=tree[ls].len()*t; tree[rs].sum+=tree[rs].len()*t;t=0;//清空标记}void update(ll l,ll r,ll a,ll p){if(tree[p].L==l&&tree[p].R==r){tree[p].add+=a;tree[p].sum+=(r-l+1)*a;return ;}ll mid=(tree[p].L+tree[p].R)>>1;down(p);//由于要修改下面的区间的值了,所以先把未下传的标记下传if(r<=mid)update(l,r,a,ls);else if(l>mid)update(l,r,a,rs);else{update(l,mid,a,ls);update(mid+1,r,a,rs);}Up(p);//向上合并一下}ll query(ll l,ll r,ll p){if(l==tree[p].L&&r==tree[p].R)return tree[p].sum;down(p);ll mid=tree[p].L+tree[p].R>>1;if(r<=mid)return query(l,r,ls);if(l>mid)return query(l,r,rs);else{return query(l,mid,ls)+query(mid+1,r,rs);//原因见配套notepad}}int main(){cin>>n>>m;for(ll i=1;i<=n;i++)cin>>a[i];build(1,n,1);while(m--){ll k;cin>>k;if(k==1){ll x,y,t;cin>>x>>y>>t;update(x,y,t,1);}else{ll x,y;cin>>x>>y;cout<<query(x,y,1)<<endl;}}return 0;}
用于前缀和优化
#include <iostream>using namespace std ;const int maxn = 5e5 + 9 ;int n , m , nxt ;int a[maxn] , c[maxn] ;int lowbit(int x ){return x & -x ;}void add(int x , int d ){for(int i = x ; i <= n ; i += lowbit(i) )c[i] += d ;}int sum(int x ){int res = 0 ;for(int i = x ; i ; i -= lowbit(i) )res += c[i] ;return res ;}signed main(){cin >> n >> m ;for(int i = 1 ; i <= n ; i++ ){int x ; cin >> x ;add(i , x - nxt ) ;nxt = x ;}while( m-- ){char op ; cin >> op ;if(op == 'C'){int l , r , d ; cin >> l >> r >> d ;add(l , d ) , add(r + 1 , -d) ;}else{int x ; cin >> x ;cout << sum(x ) << '\n' ;}}}
st表建树 ,查询是 的
//求静态区间最大值#include <bits/stdc++.h>using namespace std ;const int maxn = 1e5 + 7 , Mod = 1e9 + 7 ;int n , m , cnt ;int lg[maxn] , st[maxn][22] ;int read(){int res = 0 , f = 1 ;char ch = getchar() ;while(ch > '9' || ch < '0' ){if(ch == '-' ) f = -1 ;ch = getchar() ;}while(ch >= '0' && ch <= '9' ){res = res * 10 + ch - '0' ;ch = getchar() ;}return res * f ;}void build(){for(int j = 1 ; j <= lg[n] ; j++ )for(int i = 1 ; i <= n - (1 << j) + 1 ; i++ )st[i][j] = max(st[i][j - 1] , st[i + (1 << j - 1)][j - 1] ) ;}int query(int l , int r ){int mid = r - l + 1 ;mid = lg[mid] ;return max(st[l][mid] , st[r - (1 << mid) + 1][mid] ) ;}signed main(){cin >> n >> m ;cin >> st[1][0] ;for(int i = 2 ; i <= n ; i++ ){lg[i] = lg[i >> 1] + 1 ;cin >> st[i][0] ;}build() ;while( m-- ){int l = read() , r = read() ;cout << query(l , r ) << '\n' ;}}
#include <iostream>using namespace std ;int fa[30007] , siz[30007] , d[30007];int find(int x ){if(fa[x] == x ) return x ;int root = find(fa[x] ) ;d[x] += d[fa[x]] ;return fa[x] = root ;}void merge(int x , int y ){if(x == y ) return ;fa[x] = y ;d[x] = siz[y] ;siz[y] += siz[x] ;}int n , t ;signed main(){cin >> t ;for(int i = 1 ; i <= 30007 ; i++ ) fa[i] = i , siz[i] = 1 ;while( t-- ){char op ;int x , y ;cin >> op >> x >> y ;if(op == 'M') merge(find(x) , find(y) ) ;else{if(find(y) != find(x) ) puts("-1") ;else cout << max(abs(d[y] - d[x] ) - 1 , 0 ) << '\n' ;}}}
//普通并查集的合并操作int find(int x ){if(fa[x] == x ) return x ;return fa[x] = find(fa[x] ) ;}
#include <bits/stdc++.h>using namespace std;int n,block,cnt;int a[100010],addv[400],belong[100010];vector<int> vc[400];void pre(){for(int i=1;i<=cnt;i++){sort(vc[i].begin(),vc[i].end());}}void update(int blockn){vc[blockn].clear();for(int i=(blockn-1)*block+1;i<=blockn*block;i++){vc[blockn].push_back(a[i]);}sort(vc[blockn].begin(),vc[blockn].end());}void modify(int l,int r,int add){for(int i=l;i<=min(belong[l]*block,r);i++){a[i]+=add;}update(belong[l]);if(belong[l]!=belong[r]){for(int i=(belong[r]-1)*block+1;i<=r;i++){a[i]+=add;}update(belong[r]);}for(int i=belong[l]+1;i<belong[r];i++){addv[i]+=add;}}int query(int l,int r,int maxn){int ans=-0x3f3f3f3f;for(int i=l;i<=min(belong[l]*block,r);i++){if(a[i]+addv[belong[i]]<maxn){ans=max(ans,a[i]+addv[belong[i]]);}}if(belong[l]!=belong[r]){for(int i=(belong[r]-1)*block+1;i<=r;i++){if(a[i]+addv[belong[i]]<maxn){ans=max(ans,a[i]+addv[belong[i]]);}}}for(int i=belong[l]+1;i<belong[r];i++){if(vc[i].at(0)+addv[i]>=maxn){continue;}int k=lower_bound(vc[i].begin(),vc[i].end(),maxn-addv[i])-vc[i].begin();ans=max(ans,vc[i].at(k-1)+addv[i]);}return ans;}int main(){int n;cin>>n;block=sqrt(n);for(int i=1;i<=n;i++){scanf("%d",&a[i]);belong[i]=(i-1)/block+1;vc[belong[i]].push_back(a[i]);if(i%block==1){cnt++;}}pre();for(int i=1;i<=n;i++){int opt,l,r,c;scanf("%d%d%d%d",&opt,&l,&r,&c);if(opt==0){modify(l,r,c);}else{int k=query(l,r,c);if(k==-0x3f3f3f3f){printf("-1\n");continue;}printf("%d\n",k);}}}
void tupo(){for(int i = 1 ; i <= n ; i++ ) if(!rd[i]) q.push(i ) ;while( ! q.empty() ){int u = q.front() ; q.pop() ;ans.push_back(u ) ;for(int i = head[u] ; i ; i = ed[i].nxt ){int v = ed[i].to ;rd[v]-- ;if(! rd[v] ) q.push(v ) ;}}}
/*见识到了,这就是缩点的板子吗???整体思路:1、将整张图跑一边tarjan将每个强连通分量都缩成一个点来处理(即将每个强连通分量的权值都加在同一个点上)----> 这一步用一个数组来实现2、用拓扑序重建整张图3、在重建的图上跑DP*/#include <bits/stdc++.h>#define maxn 101010#define int long longusing namespace std;int n,m;int cnt_tup,ans,res,cnt_ad,tot;int head[maxn],dfn[maxn],low[maxn],lian_t_k[maxn],dis_lian_t[maxn],rdd[maxn],cdd[maxn],tupo_x[maxn],dis_d[maxn],f[maxn];bool pd[maxn];vector<int>q;//tarjanvector<int>rd[maxn],cd[maxn];vector<int>tup;//tupoinline int read(){int x=0,f=1;char ch=getchar();while (ch<'0'||ch>'9')if (ch=='-') f=-1;ch=getchar();while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}return x*f;}struct node{int nxt,frm,to;}ed[maxn*10];void add(int u,int v){ed[++cnt_ad].nxt=head[u];ed[cnt_ad].frm=u;ed[cnt_ad].to=v;head[u]=cnt_ad;}void tarjan(int u){dfn[u]=low[u]=++tot;q.push_back(u);pd[u]=true;for(int i=head[u];i;i=ed[i].nxt){int v=ed[i].to;if(!dfn[v]){tarjan(v);low[u]=min(low[u],low[v]);}else if(pd[v])low[u]=min(low[u],low[v]);}if(dfn[u]==low[u]){dis_lian_t[++res]+=dis_d[u];pd[u]=false;lian_t_k[u]=res;while(q.back()!=u){int w=q.back();q.pop_back();pd[w]=false;dis_lian_t[res]+=dis_d[w];lian_t_k[w]=res;}q.pop_back();}}void topu(){for(int i=1;i<=res;i++){if(!rdd[i])tup.push_back(i);}int w=tup.back();q.pop_back();tupo_x[++cnt_tup]=w;for(int i=0;i<cd[w].size();i++){int v=cd[w][i];rdd[v]--;if(!rdd[v])tup.push_back(v);}}signed main(){cin>>n>>m;for(int i=1;i<=n;i++)cin>>dis_d[i];//dis_d[i]=read();while(m--){int u,v;cin>>u>>v;//u=read(),v=read();add(u,v);}//----------------------------------> tarjan求强连通分量for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);//---------------------------------> topu重建边for(int i=1;i<=cnt_ad;i++){int x=ed[i].frm,y=ed[i].to;if(lian_t_k[x]!=lian_t_k[y]){int a,b;a=lian_t_k[x],b=lian_t_k[y];rdd[y]++,cdd[x]++;cd[x].push_back(y);rd[y].push_back(x);}}topu();//---------------------------------> dp求点权最大的路径for(int i=1;i<=res;i++){int w=tupo_x[i];//tupo序的第i个数的强连通分量的编号f[w]=dis_lian_t[w];for(int j=0;j<rd[w].size();j++){int u=rd[w][j];f[w]=max(f[w],f[u]+dis_lian_t[w]);}}for(int i=1;i<=res;i++)ans=max(f[i],ans);cout<<ans;return 0;}// 我*你妈ghc,你TM太卷了,闲的!写尼玛的缩点!!! cnmd!!! nmsl!!!
#include<bits/stdc++.h>using namespace std ;const int maxn = 1e4 + 7 ;struct node{int nxt , to , vis ;}ed[maxn << 1] ;int n , m , cnt ;int dis[maxn] , num[maxn] , head[maxn] ;bool pd[maxn] ;queue<int> q ;void add(int u , int v , int w){ed[++cnt].nxt = head[u] ;ed[cnt].to = v ;ed[cnt].vis = w ;head[u] = cnt ;}bool spfa(){for(int i = 1 ; i <= n ; i++ ) q.push(i), pd[i] = true ;while(! q.empty()){int u = q.front() ; q.pop() ;for(int i = head[u] ; i ; i = ed[i].nxt){int v = ed[i].to ; int w = ed[i].vis ;if(dis[v] > dis[u] + w){dis[v] = dis[u] + w ;q.push(v) ; num[v] = num[u] + 1 ;if(num[v] > n){pd[v] = true ; // puts("Yes") ;return 0 ;}}}}return 1 ;}signed main(){cin >> n >> m ;while(m--){int u , v , w ;cin >> u >> v >> w ;add(u , v , w) ;}if(! spfa()) puts("Yes") ;else puts("No") ;return 0 ;}
#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int MaxN = 200000 + 5, MaxM = 200000 + 5;int N, M;int U[MaxM], V[MaxM], W[MaxM];bool used[MaxM];int par[MaxN], Best[MaxN];void init() {scanf("%d %d", &N, &M);for (int i = 1; i <= M; ++i)scanf("%d %d %d", &U[i], &V[i], &W[i]);}void init_dsu() {for (int i = 1; i <= N; ++i)par[i] = i;}int get_par(int x) {if (x == par[x]) return x;else return par[x] = get_par(par[x]);}inline bool Better(int x, int y) {if (y == 0) return true;if (W[x] != W[y]) return W[x] < W[y];return x < y;}void Boruvka() {init_dsu();int merged = 0, sum = 0;bool update = true;while (update) {update = false;memset(Best, 0, sizeof Best);for (int i = 1; i <= M; ++i) {if (used[i] == true) continue;int p = get_par(U[i]), q = get_par(V[i]);if (p == q) continue;if (Better(i, Best[p]) == true) Best[p] = i;if (Better(i, Best[q]) == true) Best[q] = i;}for (int i = 1; i <= N; ++i)if (Best[i] != 0 && used[Best[i]] == false) {update = true;merged++; sum += W[Best[i]];used[Best[i]] = true;par[get_par(U[Best[i]])] = get_par(V[Best[i]]);}}if (merged == N - 1) printf("%d\n", sum);else puts("impossible");}int main() {init();Boruvka();return 0;}
int n , m , tot , cnt , ans ;struct node{int to , nxt , dis ;}ed[maxn] ;int dis[maxn] , head[maxn] ;bool pd[maxn] ;void add(int u , int v , int w){ed[++cnt].to = v ;ed[cnt].dis = w ;ed[cnt].nxt = head[u] ;head[u] = cnt ;}priority_queue<pii , vector<pii> , greater<pii> > q ;int prim(){int res = 0 ;memset(dis , 0x3f , sizeof(dis)) ;dis[1] = 0 ; q.push({0 , 1}) ;while(! q.empty()){int u = q.top().second , val = q.top().first ; q.pop() ;if(pd[u]) continue ; pd[u] = true ; res += val ; tot++ ;for(int i = head[u] ; i ; i = ed[i].nxt ){int v = ed[i].to ;if(dis[v] > ed[i].dis){// orz ;dis[v] = ed[i].dis ;/* if(!pd[v])q.push({dis[v] , v}) ;*/q.push({ dis[v] , ed[i].to}) ;}}}if(tot != n) return 0x3f3f3f3f ;return res ;}signed main(){cin >> n >> m ;while( m-- ){int u , v , w ;cin >> u >> v >> w ;add(u , v , w) ;add(v , u , w) ;}ans = prim() ;//cout << tot ;if(ans == 0x3f3f3f3f) puts("impossible") ;else cout << ans ;return 0 ;}
正如其他物种一样,奶牛们也喜欢在排队打饭时与它们的朋友挨在一起。FJ 有编号为 的 头奶牛 。开始时,奶牛们按照编号顺序来排队。奶牛们很笨拙,因此可能有多头奶牛在同一位置上。
有些奶牛是好基友,它们希望彼此之间的距离小于等于某个数。有些奶牛是情敌,它们希望彼此之间的距离大于等于某个数。
给出 对好基友的编号,以及它们希望彼此之间的距离小于等于多少;又给出 对情敌的编号,以及它们希望彼此之间的距离大于等于多少 。
请计算:如果满足上述所有条件, 号奶牛和 号奶牛之间的距离最大为多少
第一行:三个整数 ,用空格分隔。
第 行:每行三个整数 ,用空格分隔,表示 号奶牛与 号奶牛之间的距离须 。保证 .
第 行:每行三个整数 ,用空格分隔,表示 号奶牛与 号奶牛之间的距离须 。保证 .
一行,一个整数。如果没有合法方案,输出 -1. 如果有合法方案,但 号奶牛可以与 号奶牛相距无穷远,输出 -2. 否则,输出 号奶牛与 号奶牛间的最大距离。
#include <bits/stdc++.h>#define int long long#define orz cout << "xyc_ak_ioi"using namespace std ;const int maxn = 1e6 + 7 ; const int MAX = 1e5 + 7 ;int n , m1 , m2 , cnt , ans ;int dis[maxn] , head[maxn] , num[maxn] ;bool pd[maxn] ;inline int read(){int x = 0 , f = 1 ;char ch = getchar() ;while(ch < '0' || ch > '9' ){if(ch == '-') f = -1 ;ch = getchar() ;}while(ch >= '0' && ch <= '9'){x = x * 10 + ch - 48 ;ch = getchar() ;}return x * f ;}struct node{int to , nxt , vis ;} ed[maxn << 1] ;void add(int u , int v , int dis){ed[++cnt].to = v ;ed[cnt].vis = dis ;ed[cnt].nxt = head[u] ;head[u] = cnt ;}bool spfa(int k){queue<int> q ;memset(dis , 0x3f , sizeof(dis)) ;memset(pd , 0 , sizeof(pd)) ;memset(num , 0 , sizeof(num)) ;for(int i = 1 ; i <= k ; i++ ){pd[i] = true ; q.push(i) ;dis[i] = 0 ;}/*q.push(1) ;dis[1] = 0 ; pd[1] = true ;*/while(!q.empty()){//orz ;int u = q.front() ; q.pop() ;pd[u] = false ;for(int i = head[u] ; i ; i = ed[i].nxt){int v = ed[i].to , val = ed[i].vis ;if(dis[v] > dis[u] + val){dis[v] = dis[u] + val ;num[v] = num[u] + 1 ;if(num[v] > n) return false ;if(!pd[v]) q.push(v) , pd[v] = true ;}}}return true ;}signed main(){cin >> n >> m1 >> m2 ;// add(0 , 1 , 0x3f3f3f) ;for(int i = 2 ; i <= n ; i++ ) add(i , i - 1 , 0) ;while( m1-- ){int a = read() , b = read() , dis = read() ;add(a , b , dis) ;}while( m2-- ){int a = read() , b = read() , dis = read() ;add(b , a , -dis) ;}if(! spfa(n)) puts("-1") ;else{spfa(1) ;if(dis[n] >= 0x3f3f3f3f) cout << "-2" ;else cout << dis[n] ;}return 0 ;}
1、二分图的判定
#include <bits/stdc++.h>using namespace std ;const int maxn = 1e5 + 7 ;struct node{int to , nxt ;} ed[maxn << 1 ] ;int clr[maxn] , head[maxn] ;int cnt , n , m ;void add(int u , int v ){ed[++cnt] = { v , head[u] } ;head[u] = cnt ;}bool dfs(int u , int op ){clr[u] = op ;for(int i = head[u] ; i ; i = ed[i].nxt ){int v = ed[i].to ;if(clr[v] == -1 ){if(! dfs(v , !op)) return false ;}else if(clr[v] == op) return false ;}return true ;}signed main(){cin >> n >> m ;while( m-- ){int u , v ;cin >> u >> v ;add(u , v ) ; add( v , u ) ;}memset(clr , -1 , sizeof clr ) ;for(int i = 1 ; i <= n ; i++ ){if(clr[i] == -1 ){int flg = dfs(i , 0) ;if(! flg){puts("No") ;return 0 ;}}}cout << "Yes" ;return 0 ;}
2、二分图的最大匹配
#include <bits/stdc++.h>using namespace std ;const int maxn = 1e5 + 7 ;int n , m , cnt , ans , N ;int hus[501] , head[501] ;bool pd[501] ;struct node{int to , nxt ;} ed[maxn] ;void add(int u , int v ){ed[++cnt] = { v , head[u] } ;head[u] = cnt ;}bool find(int u ){for(int i = head[u] ; i ; i = ed[i].nxt ){int v = ed[i].to ;if(!pd[v]){pd[v] = true ;if(! hus[v] || find(hus[v])){hus[v] = u ;return true ;}}}return false ;}signed main(){cin >> n >> N >> m ;while( m-- ){int u , v ;cin >> u >> v ; add(u , v ) ;}for(int i = 1 ; i <= n ; i++ ){memset(pd , false , sizeof pd ) ;if(find(i) ) ans++ ;}cout << ans ;return 0 ;}
bool check(int x )//艹,丢人了。这题居然看了模板……!{if(x < 2 ) return false ;for(int i = 2 ; i <= x / i ; i++ ){if(x % i ) continue ;else return false ;}return true ;}
void check(int n ){for(int i = 2 ; i <= n / i ; i++ ){int now = 0 ;//int x = n ;//if(n % i == 0 )// cout << i << " " ;while(n % i == 0 ){now++ ;n /= i ;}if(now ) cout << i << " " << now << '\n' ;}if(n > 1) cout << n << " " << 1 << '\n' ;}
void check(int x ){q.clear() ;for(int i = 1 ; i <= x / i ; i++ ){if(x % i == 0 ){q.push_back(i) ;if(x / i != i) q.push_back(x / i ) ;}}sort(q.begin() , q.end()) ;for(auto i : q ){cout << i << " ";}puts("") ;}
void erlu(){for(int i = 2 ; i <= n ; i++ ){if(! pd[i] ) prime[++cnt] = i ;for(int j = 1 ; prime[j] * i <= n ; j++ ){pd[prime[j] * i ] = true ;if(i % prime[j] == 0 ) break ;}}}