T1 math
就挺水一小破题目,第一眼看好像不可做,看着看着突然发现假设x和y的最大公约数是gcd,那么kx%y一定是gcd的倍数,
然后想到可以把所有数字与k的gcd求出来,打一个完全背包,可是仔细一算肯定会t掉,然后又仔细想了下,发现既然都是gcd的倍数
那么只要把所有的数求一个gcd就可以满足情况了,最后直接在k的范围内往上加gcd,O(n)直接切了
不过跑大样例的时候,文本比较总是wa,可是看文件字节大小,以及拿肉眼看都一样,有点玄学,开大样例的时候,gedit直接卡爆了,直接白屏了
被迫提交代码重启。。。不过这题确实挺水的,某XIN直接跑rand都切了,可是赛时只有9个人切了,大家的基本功还是不扎实,好好练;
1 #include<bits/stdc++.h>//瞎jb搞就行了 2 using namespace std; 3 inline int read() 4 { 5 int x=0,f=1; 6 char ch=getchar(); 7 while(ch<'0'||ch>'9') 8 { 9 if(ch=='-') 10 f=-1; 11 ch=getchar(); 12 } 13 while(ch>='0'&&ch<='9') 14 { 15 x=(x<<1)+(x<<3)+(ch^48); 16 ch=getchar(); 17 } 18 return x*f; 19 } 20 inline int min(int x,int y){return x<y?x:y;} 21 inline int max(int x,int y){return x>y?x:y;} 22 inline void swap(int &x,int &y){x^=y^=x^=y;} 23 inline int abs(int x){return x<0?-x:x;} 24 const int maxn=5e5+1; 25 int n,k; 26 int a[maxn]; 27 int gcd; 28 bool b[2000000]; 29 inline int Gcd(int a,int b) 30 { 31 if(!b) 32 return a; 33 return Gcd(b,a%b); 34 } 35 int main() 36 { 37 n=read(); 38 k=read(); 39 gcd=k; 40 int ans=0; 41 for(int i=1;i<=n;i++) 42 { 43 a[i]=read(),gcd=Gcd(a[i],gcd); 44 } 45 b[0]=1; 46 for(int i=1;i<=k;i++) 47 { 48 b[(i*gcd)%k]=1; 49 } 50 for(int i=0;i<=k;i++) 51 if(b[i]) 52 ans++; 53 printf("%d\n",ans); 54 for(int i=0;i<=k;i++) 55 if(b[i]) 56 printf("%d ",i); 57 }
T2 biology
这个题第一眼看这个式子觉得可能在考矩阵,可是仔细一看式子就不是了,由于这个题他说a[ xi ][ yi ]要小于a[ x(i+1) ][ y(i+1) ]的,所以考虑对这些进行离散化
将所有点进行分层,一层一层地转移,我们把绝对值拆开,拆成f[ x ][ y ]+x+y,f[ x ][ y ]+x-y,f[ x ][ y ]-x+y和f[ x ][ y ]-x-y,来表示xi,yi与x(i-1)y(i-1)的关系,
我们维护这种情况这个区间范围的最大值,用来进行下层的转移,考试的时候写了4个树状数组来维护最值,复杂度O(nlog( n )mlog( m )),只能拿到80分
考试后发现,其实根本没有必要用树状数组,因为只要满足每层最大的那种情况就好了,所以说直接记录4个变量来维护就好,一个常数稍微大一点的O(mn)
直接切了
1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 inline int read() 5 { 6 int x=0,f=1; 7 char ch=getchar(); 8 while(ch<'0'||ch>'9') 9 { 10 if(ch=='-') 11 f=-1; 12 ch=getchar(); 13 } 14 while(ch>='0'&&ch<='9') 15 { 16 x=(x<<1)+(x<<3)+(ch^48); 17 ch=getchar(); 18 } 19 return x*f; 20 } 21 inline void swap(int &x,int &y){x^=y^=x^=y;} 22 inline int abs(int x){return x<0?-x:x;} 23 int n,m; 24 int a[2001][2001],b[2001][2001]; 25 int dp[2001][2001]; 26 struct node{ 27 int l,r; 28 }; 29 vector<node> q[1000001]; 30 bool app[1000001]; 31 int num[1000001]; 32 int val[1000001],key[1000001],cnt,maxx; 33 struct szsz 34 { 35 int c[2001][2001]; 36 inline int lowbit(int x){return x&-x;} 37 void update(int x,int y,int val) 38 { 39 for(int i=x;i<=n;i+=lowbit(i)) 40 for(int j=y;j<=m;j+=lowbit(j)) 41 c[i][j]=max(c[i][j],val); 42 } 43 inline int query(int x,int y) 44 { 45 int val=0; 46 for(int i=x;i;i-=lowbit(i)) 47 for(int j=y;j;j-=lowbit(j)) 48 val=max(val,c[i][j]); 49 return val; 50 } 51 }c1,c2,c3,c4; 52 signed main() 53 { 54 n=read(); 55 m=read(); 56 for(int i=1;i<=n;i++) 57 { 58 for(int j=1;j<=m;j++) 59 { 60 a[i][j]=read(); 61 if(!app[a[i][j]]&&a[i][j]) 62 { 63 app[a[i][j]]=1; 64 num[++cnt]=a[i][j]; 65 } 66 } 67 } 68 for(int i=1;i<=n;i++) 69 { 70 for(int j=1;j<=n;j++) 71 { 72 b[i][j]=read(); 73 } 74 } 75 sort(num+1,num+cnt+1); 76 for(int i=1;i<=cnt;i++) 77 { 78 key[num[i]]=i; 79 } 80 for(int i=1;i<=n;i++) 81 { 82 for(int j=1;j<=n;j++) 83 { 84 if(!a[i][j]) 85 continue; 86 node x; 87 x.l=i,x.r=j; 88 q[key[a[i][j]]].push_back(x); 89 } 90 } 91 int sz=q[1].size(); 92 for(int i=0;i<sz;i++) 93 { 94 int x=q[1][i].l,y=q[1][i].r; 95 c1.update(x,y,b[x][y]-x-y); 96 c2.update(x,m-y+1,b[x][y]-x+y); 97 c3.update(n-x+1,y,b[x][y]+x-y); 98 c4.update(n-x+1,m-y+1,b[x][y]+x+y); 99 } 100 for(int i=2;i<=cnt;i++) 101 { 102 sz=q[i].size(); 103 for(int j=0;j<sz;j++) 104 { 105 int maxx=0,x=q[i][j].l,y=q[i][j].r; 106 maxx=c1.query(x,y)+x+y+b[x][y]; 107 dp[x][y]=max(maxx,dp[x][y]); 108 maxx=c2.query(x,m-y+1)+x-y+b[x][y]; 109 dp[x][y]=max(maxx,dp[x][y]); 110 maxx=c3.query(n-x+1,y)-x+y+b[x][y]; 111 dp[x][y]=max(maxx,dp[x][y]); 112 maxx=c4.query(n-x+1,m-y+1)-x-y+b[x][y]; 113 dp[x][y]=max(maxx,dp[x][y]); 114 } 115 for(int j=0;j<sz;j++) 116 { 117 int x=q[i][j].l,y=q[i][j].r; 118 c1.update(x,y,dp[x][y]-x-y); 119 c2.update(x,m-y+1,dp[x][y]-x+y); 120 c3.update(n-x+1,y,dp[x][y]+x-y); 121 c4.update(n-x+1,m-y+1,dp[x][y]+x+y); 122 } 123 } 124 int ans=0; 125 for(int i=1;i<=n;i++) 126 { 127 for(int j=1;j<=m;j++) 128 { 129 ans=max(ans,dp[i][j]); 130 } 131 } 132 cout<<ans; 133 }
1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; 4 inline int read() 5 { 6 int x=0,f=1; 7 char ch=getchar(); 8 while(ch<'0'||ch>'9') 9 { 10 if(ch=='-') 11 f=-1; 12 ch=getchar(); 13 } 14 while(ch>='0'&&ch<='9') 15 { 16 x=(x<<1)+(x<<3)+(ch^48); 17 ch=getchar(); 18 } 19 return x*f; 20 } 21 struct node{ 22 int l,r; 23 }; 24 inline int max(int x,int y){return x<y?y:x;} 25 inline int min(int x,int y){return x>y?y:x;} 26 inline int abs(int x,int y){return x<0?-x:x;} 27 inline void swap(int &x,int &y){x^=y^=x^=y;} 28 const int maxn=2001; 29 const int maxm=1e6+5; 30 const int inf=1e15+1; 31 int a[maxn][maxn],b[maxn][maxn]; 32 int dp[maxn][maxn]; 33 int key[maxm],x,y,rx,ry,mx1,mx2,mx3,mx4,num[maxm],n,m,cnt; 34 bool app[maxm]; 35 vector<node> q[maxm]; 36 inline int realx(int x,int y){return (x+y)>>1;}//这是真正的x,y坐标 37 inline int realy(int x,int y){return (x-y)>>1;}//突然发现,好像转不转换都一样 38 signed main() 39 { 40 n=read(); 41 m=read(); 42 for(int i=1;i<=n;i++) 43 { 44 for(int j=1;j<=m;j++) 45 { 46 a[i][j]=read(); 47 if(!app[a[i][j]]&&a[i][j]) 48 { 49 num[++cnt]=a[i][j]; 50 app[a[i][j]]=1; 51 } 52 } 53 } 54 for(int i=1;i<=n;i++) 55 { 56 for(int j=1;j<=m;j++) 57 b[i][j]=read(); 58 } 59 sort(num+1,num+1+cnt); 60 for(int i=1;i<=cnt;i++) 61 { 62 key[num[i]]=i; 63 } 64 for(int i=1;i<=n;i++) 65 { 66 for(int j=1;j<=m;j++) 67 { 68 if(!a[i][j]) 69 continue; 70 q[key[a[i][j]]].push_back({i+j,i-j}); 71 } 72 } 73 mx1=mx2=mx3=mx4=-inf; 74 int sz=q[1].size(); 75 for(int i=0;i<sz;i++) 76 { 77 x=q[1][i].l,y=q[1][i].r; 78 rx=realx(x,y),ry=realy(x,y); 79 mx1=max(mx1,b[rx][ry]-x); 80 mx2=max(mx2,b[rx][ry]-y); 81 mx3=max(mx3,b[rx][ry]+y); 82 mx4=max(mx4,b[rx][ry]+x); 83 } 84 int maxx=0; 85 for(int i=2;i<=cnt;i++) 86 { 87 sz=q[i].size(); 88 for(int j=0;j<sz;j++) 89 { 90 x=q[i][j].l,y=q[i][j].r; 91 rx=realx(x,y),ry=realy(x,y); 92 maxx=0; 93 maxx=max(maxx,mx1+x); 94 maxx=max(maxx,mx2+y); 95 maxx=max(maxx,mx3-y); 96 maxx=max(maxx,mx4-x); 97 dp[rx][ry]=maxx+b[rx][ry]; 98 } 99 for(int j=0;j<sz;j++) 100 { 101 x=q[i][j].l,y=q[i][j].r; 102 rx=realx(x,y),ry=realy(x,y); 103 mx1=max(mx1,dp[rx][ry]-x); 104 mx2=max(mx2,dp[rx][ry]-y); 105 mx3=max(mx3,dp[rx][ry]+y); 106 mx4=max(mx4,dp[rx][ry]+x); 107 } 108 } 109 int ans=0; 110 for(int i=1;i<=n;i++) 111 { 112 for(int j=1;j<=m;j++) 113 ans=max(ans,dp[i][j]); 114 } 115 cout<<ans; 116 }
T3 english
考试的时候一直在调t2,调过了之后,就只剩2分钟了,没来得及写这题,考完之后发现随便打个线段树,然后再利用特殊性质直接输出0,就能骗到30分,10分钟左右吧
挺气的,以后还是先把每个题的暴力打出来再说吧,其实这道题的部分分数是很多的
我们先来看ans1,首先我们统计一下这个在i之前二进制第k位是1的数的个数,然后写一个单调栈,求出以i为最大值的最大区间来,然后枚举这n个区间,我们利用启发式合并的原理,
跑一个比较小的区间,然后用另外一半来匹配,挺好推的,式子就不过多阐述了。
重点是ans2
ans2的话需要用到可持久化trie树,可以用那个来查询出异或a[ r ]>a[ i ]的 l 的个数,那么不会可持久化trie树的话,建议从主席树开始看一下,剩下的就没啥了
1 #include<bits/stdc++.h> 2 #define lid id<<1 3 #define rid id<<1|1 4 #define int long long 5 using namespace std; 6 inline int read() 7 { 8 int x=0,f=1; 9 char ch=getchar(); 10 while(ch<'0'||ch>'9') 11 { 12 if(ch=='-') f=-1; 13 ch=getchar(); 14 } 15 while(ch>='0'&&ch<='9') 16 { 17 x=(x<<1)+(x<<3)+(ch^48); 18 ch=getchar(); 19 } 20 return x*f; 21 } 22 const int maxn=1e5+1; 23 const int mod=1e9+7; 24 int n,m; 25 int a[maxn]; 26 int f[maxn][22]; 27 int le[maxn]; 28 int re[maxn],ans1,ans2,opt; 29 stack<int >s; 30 struct seg_tree{ 31 int l,r,maxx; 32 }tr[maxn<<2]; 33 struct tire{ 34 int cnm,root[maxn],ch[maxn*22][2],size[maxn*22]; 35 void insert(int pre,int &now,int i,int x) 36 { 37 now=++cnm; 38 size[now]=size[pre]; 39 if(i<0){size[now]++;return ;} 40 int d=(x>>i)&1; 41 ch[now][d^1]=ch[pre][d^1]; 42 insert(ch[pre][d],ch[now][d],i-1,x); 43 size[now]=size[ch[now][0]]+size[ch[now][1]]; 44 return ; 45 } 46 void ins(int x,int pos){insert(root[pos-1],root[pos],20,x);} 47 int query(int x,int y,int pos) 48 { 49 int p=root[pos],res=0; 50 for(int i=20;i>=0;i--) 51 { 52 int a=(x>>i)&1,b=(y>>i)&1; 53 if(!b) 54 { 55 res+=size[ch[p][a^1]]; 56 p=ch[p][a]; 57 } 58 else p=ch[p][a^1]; 59 if(!p) break; 60 } 61 return res; 62 } 63 }p; 64 void cz(int k,int l,int r) 65 { 66 if(k-l<r-k) 67 { 68 for(int j=l;j<=k;j++) 69 { 70 (ans1+=a[j]*a[k]%mod*(r-k+1)%mod)%=mod; 71 for(int i=20;i>=0;i--) 72 { 73 int now=(a[j]>>i)&1; 74 if(!now)(ans1+=(1<<i)*(f[r][i]-f[k-1][i])%mod*a[k]%mod)%=mod; 75 else (ans1-=(1<<i)*(f[r][i]-f[k-1][i])%mod*a[k]%mod)%=mod,ans1=(ans1+mod)%mod; 76 } 77 ans2=(ans2+(p.query(a[j],a[k],r)-p.query(a[j],a[k],k-1)+mod)%mod*a[k]%mod)%mod; 78 } 79 } 80 else 81 { 82 for(int j=k;j<=r;j++) 83 { 84 (ans1+=a[j]*a[k]%mod*(k-l+1)%mod)%=mod; 85 for(int i=20;i>=0;i--) 86 { 87 int now=(a[j]>>i)&1; 88 if(!now)(ans1+=(1<<i)*(f[k][i]-f[l-1][i])%mod*a[k]%mod)%=mod; 89 else (ans1-=(1<<i)*(f[k][i]-f[l-1][i])%mod*a[k]%mod)%=mod,ans1=(ans1+mod)%mod; 90 } 91 ans2=(ans2+(p.query(a[j],a[k],k)-p.query(a[j],a[k],l-1)+mod)%mod*a[k]%mod)%mod; 92 } 93 } 94 } 95 signed main() 96 { 97 n=read(),opt=read(); 98 for(int i=1;i<=n;i++) 99 a[i]=read(),p.ins(a[i],i); 100 for(int i=1;i<=n;i++) 101 { 102 for(int j=0;j<=20;j++) 103 { 104 f[i][j]+=f[i-1][j]; 105 if((a[i]>>j)&1)f[i][j]++; 106 } 107 } 108 for(int i=1;i<=n;i++) 109 { 110 while(!s.empty()&&a[i]>a[s.top()])s.pop(); 111 le[i]=s.empty()?1:s.top()+1; 112 s.push(i); 113 } 114 while(!s.empty()) 115 s.pop(); 116 for(int i=n;i;i--) 117 { 118 while(!s.empty()&&a[i]>=a[s.top()])s.pop(); 119 re[i]=s.empty()?n:s.top()-1; 120 s.push(i); 121 } 122 for(int i=1;i<=n;i++) 123 cz(i,le[i],re[i]); 124 if(opt==1||opt==3) 125 cout<<ans1<<endl; 126 if(opt==2||opt==3) 127 cout<<ans2<<endl; 128 }