题1:
题2(好大的Gcd(gcd.cpp)):
题目描述
定义一个6位数是lucky的,当且仅当它的前3位之和等于后3位之和,比如165912
给出数x,找出最小的、大于x的幸运数字。
无解输出-1.
格式
输入:一个数,表示x
输出:一个数,表示下一个幸运数字
范围:
Sample Input 0
555555
Sample Output 0
555564
#include<bits/stdc++.h> using namespace std; inline int read() { int x=0,w=0; char ch=0; while(!isdigit(ch)) {w|=ch=='-';ch=getchar();} while(isdigit(ch)) {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();} return w? -x:x; } const int N=1e6+6; int n,j,c1,c2; int a[1001000],b[1001000],c[N],aa[N],bb[N]; #define fr(x) for(int i=1;i<=n;i++) int main() { n=read(); for(int i=1;i<=n;i++) a[i]=read(); for(int i=1;i<=n;i++) b[i]=read(); for(int i=1;i<=n;i++) c[a[i]]++; for(int i=1;i<N;i++) for(int o=i;o<N;o+=i) if(c[o]) aa[i]=max(aa[i],o); for(int i=1;i<=n;i++) c[a[i]]--; for(int i=1;i<=n;i++) c[b[i]]++; for(int i=1;i<N;i++) for(int o=i;o<N;o+=i) if(c[o]) bb[i]=max(bb[i],o); int dd=0; for(int i=1;i<=1e6+7;i++) if(aa[i]&&bb[i]) dd=i; cout<<aa[dd]+bb[dd]; return 0; }
题3(买买买):
题目描述
蓝月商场有n件宝贝,每件宝贝有两个属性:价钱price和品牌brand。其中brand是1-5之间某个整数。每件宝贝价钱两两不同。
贪玩蓝月有Q个代言人,每个代言人拍完戏之后,希望能从蓝月商场免费顺走一样宝贝。但是每个代言人有自己的喜好,例如古天乐只喜欢品牌1,陈小春喜欢品牌1或品牌2,渣渣辉喜欢品牌3和5……具体来说,代言人会有d个喜欢的品牌(1 <= d <= 5),同时他最喜欢这些品牌中,价钱第k便宜的宝贝。
请你求出每个代言人最喜欢的宝贝的价钱是多少!如果不存在这件宝贝,请输出-1.
格式
输入:第一行一个整数n,第二行n个整数描述每件宝贝的品牌,第三行n个数描述每件宝贝的价钱。第四行一个整数Q,接下来Q*3行,每3行描述一个代言人的信息。其中第一行一个整数d,第二行d个数表示喜欢的品牌,第三行一个数表示k。
输出:一共Q行,每行一个数。
范围:
Sample Input 0
3
1 1 2
1 3 2
3
1
1
2
2
1 2
2
1
3
1
Sample Output 0
3
2
-1
#include<bits/stdc++.h> using namespace std; inline int read() { int x=0,w=0; char ch=0; while(!isdigit(ch)) {w|=ch=='-';ch=getchar();} while(isdigit(ch)) {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();} return w? -x:x; } #define s(x,y) sort(x+1,x+y+1) struct xin { int p,v; }w[100010]; bool pd(xin a,xin b) { return (a.v<b.v); } int n,q,z,pz[10],k,pp[10],s1[100010],s2[100010],s3[100010],s4[100010],s5[100010]; inline int get(int k) { int j=0; for(int i=1;i<=z;i++) { if(pz[i]==1) j+=s1[k]; if(pz[i]==2) j+=s2[k]; if(pz[i]==3) j+=s3[k]; if(pz[i]==4) j+=s4[k]; if(pz[i]==5) j+=s5[k]; } return j; } int main() { n=read(); for(int i=1;i<=n;i++) w[i].p=read(); for(int i=1;i<=n;i++) w[i].v=read(); sort(w+1,w+1+n,pd); for(int i=1;i<=n;i++) { if(w[i].p==1) s1[i]=s1[i-1]+1; else s1[i]=s1[i-1]; if(w[i].p==2) s2[i]=s2[i-1]+1; else s2[i]=s2[i-1]; if(w[i].p==3) s3[i]=s3[i-1]+1; else s3[i]=s3[i-1]; if(w[i].p==4) s4[i]=s4[i-1]+1; else s4[i]=s4[i-1]; if(w[i].p==5) s5[i]=s5[i-1]+1; else s5[i]=s5[i-1]; } q=read(); for(int i=1;i<=q;i++) { z=read(); for(int o=1;o<=z;o++) pz[o]=read(); k=read(); if(get(n)<k) { printf("-1\n"); continue; } int l=1,r=n;int mid; while(l<=r) { mid=(l+r)>>1; if(get(mid)>=k) r=mid-1; else l=mid+1; } printf("%d\n",w[l].v); } return 0; }
题4(干爆字符串):,,,,
题目描述
有两个仅包含小写字母的字符串x,y,长度分别为n,m。你需要修改x串中某些字符,是的新的x串和y串的最长公共子序列长度至少为k。
我们将’a’…’z’对应成0…25,修改两个字符付出的代价,为它们对应的数的xor值。比如说,将’a’修改成’z’代价为0 xor 25=25。
请问最少付出多少代价,使得新的x串和y串的LCS大于等于k。
格式
输入:第一行三个数n,m,k,第二行长度为n的字符串x,第三行长度为m的字符串y。
输出:最小花费,如果不能请输出-1。
范围:
SampleInput 0
7 4 2
merging
pair
SampleOutput 0
3
#include<bits/stdc++.h> using namespace std; const int M=1e9; int a[555],b[555],f[555][555][2]; int main() { int n,m,k; cin>>n>>m>>k; string x,y; if(k>min(n,m)) { cout<<-1;return 0; } cin>>x>>y; for(int i=n;i>=1;i--) a[i]=x[i-1]-97; for(int i=m;i>=1;i--) b[i]=y[i-1]-97; for(int i=0;++i<=k;) { f[0][0][i&1]=M; for(int o=0;++o<=n;) f[o][0][i&1]=M; for(int o=0;++o<=m;) f[0][o][i&1]=M; for(int o=0;++o<=n;) for(int p=0;++p<=m;) f[o][p][i&1]=min(min(f[o][p-1][i&1],f[o-1][p][i&1]),f[o-1][p-1][(i&1)^1]+(a[o]^b[p])); } cout<<f[n][m][k&1]; return 0; }
题5(阶乘数组):
题目描述
给出长度为n的序列A1,A2,…,An。进行m次操作,有三种类型:
-
给出l,r,将区间[l,r]的Ai都加一。
-
阶乘数组给出l,r,询问区间[l,r]的Ai!的和,对10^9取模。
-
给出I,v,将Ai单点修改为v。
格式
输入第一行两个数n,m,第二行n个数Ai。
接下来m行,每行三个数,第一个数k,表示第几类操作,后面两个数如题所述。
输出:对于每个操作2输出解。
范围
Sample Input 0
5 7
1 1 1 1 1
2 1 5
1 1 5
2 1 5
1 1 3
2 1 5
3 1 15
2 1 5
Sample Output 0
5
10
22
674368016
3.线段树极其不熟练,想着用树状数组写(比较好写也稍微熟练些)but(考试完后修改还遇到的不可抗拒性的错误,还超时了一个)(??为什么会比线段树慢)
#include <bits/stdc++.h> using namespace std; #define ll long long const int N=1e6,P=1e9; int n,m,s; int a[N],t[N],b[41]; struct hh { int l,r,n[41],z; }tr[N]; ll v[50]={0,1,2,6,24,120,720,5040,40320,362880, 3628800,39916800,479001600,227020800,178291200, 674368000,789888000,428096000,705728000,408832000, 176640000,709440000,607680000,976640000,439360000, 984000000,584000000,768000000,504000000,616000000, 480000000,880000000,160000000,280000000,520000000, 200000000,200000000,400000000,200000000,800000000,0}; ll A; #define C getchar()-48 inline int read() { int s=0,t=1,k=C; for (;k<0||k>9;k=C) if (k==-3) t=-1; for (;k>=0&&k<=9;k=C) s=(s<<1)+(s<<3)+k; return s*t; } inline void write(long long x) { if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); } void fir() { v[1]=1; for (int i=1;++i<40;) v[i]=(v[i-1]*i)%P; } #define ls k<<1 #define rs k<<1|1 inline void bt(int k,int l,int r) //建树 { tr[k].l=l;tr[k].r=r; if (l==r) return; int M=l+r>>1; bt(ls,l,M);bt(rs,M+1,r); } //上到下传递值 inline void dow(int k) { int z=tr[k].z; if (!z) return; for (int i=40;--i;) { if (i+z<40) tr[ls].n[i+z]+=tr[ls].n[i], tr[rs].n[i+z]+=tr[rs].n[i]; tr[ls].n[i]=tr[rs].n[i]=0; } tr[ls].z+=z; tr[rs].z+=z; tr[k].z=0; } //下到上传递值 inline void ud(int k) { for (int i=40;--i;) tr[k].n[i]=tr[ls].n[i]+tr[rs].n[i]; } //读入 inline void into1(int k,int l,int s) { if (l>tr[k].r||l<tr[k].l) return; if (tr[k].l==tr[k].r) { for (int i=40;--i;) tr[k].n[i]=0; if (s<40) tr[k].n[s]=1; return; } dow(k); into1(ls,l,s); into1(rs,l,s); ud(k); } //读入 inline void into2(int k,int l,int r) { if (l>tr[k].r||r<tr[k].l) return; if (l<=tr[k].l&&tr[k].r<=r) { dow(k); for (int i=40;--i>=0;) tr[k].n[i+1]=tr[k].n[i]; ++tr[k].z; return; } dow(k); into2(ls,l,r); into2(rs,l,r); ud(k); } //累加 inline void qwe(int k,int l,int r) { if (l>tr[k].r||r<tr[k].l) return; if (l<=tr[k].l&&tr[k].r<=r) { for (int i=40;--i;) b[i]+=tr[k].n[i]; return; } dow(k); qwe(ls,l,r); qwe(rs,l,r); } int main() { cin>>n>>m; bt(1,1,n); for (int i=0;++i<=n;) { a[i]=read(); if (a[i]<40) into1(1,i,a[i]); } while (m--) { int z=read(),x=read(),y=read(); if (z==1) { if (x>y) swap(x,y); 纪念我的树状数组 ///////////// ////%%%%%//// ////%%%%%//// ////%%%%%//// ////%%%%%//// ////////////%%%%%//////////// ////%%%%%%%%%%%%%%%%%%%%%//// ////%%%%%%%%%%%%%%%%%%%%%//// ////////////%%%%%//////////// ////%%%%%//// ////%%%%%//// ////%%%%%//// ////%%%%%//// //////%%%%%%%%%%%%%%%%%////// ////%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%//// ////%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%//// ///%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/// ///%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/// ///%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/// ///%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/// ///%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%///
///%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/// ///%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/// ///%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/// ///%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/// ///%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/// ///%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/// ///%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/// ///%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/// ///%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/// ///%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%/// ////////////////////////////////////////////////// |********************************************************| |********************************************************| MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM --------------------------------------------------------------- #include<bits/stdc++.h> using namespace std; inline int read() { int x=0,w=0; char ch=0; while(!isdigit(ch)) {w|=ch=='-';ch=getchar();} while(isdigit(ch)) {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();} return w? -x:x; } inline void write(long long x) { if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); } #define cc 1000000000 #define ll long long int n,m; int a[2000000]; ll k,l,r; ll c[1000100]; ll v[50]={0,1,2,6,24,120,720,5040,40320,362880, 3628800,39916800,479001600,227020800,178291200, 674368000,789888000,428096000,705728000,408832000, 176640000,709440000,607680000,976640000,439360000, 984000000,584000000,768000000,504000000,616000000, 480000000,880000000,160000000,280000000,520000000, 200000000,200000000,400000000,200000000,800000000,0}; inline int lowbit(int k){ return (k&(-k)); } inline void into(int a,int k) { while(a<=n) { while(c[a]+k<0) c[a]+=cc; c[a]=(c[a]+k)%cc;a+=lowbit(a); } } inline ll out(int k) { ll z=0; while(k>0) { z=(z+c[k])%cc;k-=lowbit(k); } return z; } int main() { n=read(),m=read(); for(int i=1;i<=n;i++) { a[i]=read(); if(a[i]<40) into(i,a[i]); } for(int i=1;i<=m;i++) { k=read();l=read();r=read(); if(k==1) { for(int o=l;o<=r;o++) { a[o]++; if(a[o]==40) into(o,-v[39]); if(a[o]>40) continue; if(a[o]<40) into(o,(v[a[o]]-v[a[o]-1])%cc); } } if(k==2) { write(out(r)-out(l-1));printf("\n"); } if(k==3) { if(r>=40) r=40; into(l,(v[r]-v[a[l]])%cc); a[l]=40; } } return 0; } */
into2(1,x,y); } if (z==2) { A=0; memset(b,0,sizeof b); if (x>y) swap(x,y); qwe(1,x,y); for (int i=40;--i;) A=(A+v[i]*b[i]%P)%P; write(A);printf("\n"); } if (z==3) into1(1,x,y); } return 0;}
题6(二进制操作数组):
题目描述
输入格式
输出格式
数据范围
Sample Input 0
6 6
8 9 1 13 9 3
1 4 5
2 6 9
1 3 7
2 7 7
1 6 1
2 11 13
Sample Output 0
45 19 21