7.10
T1:求出一个矩阵中平均数大于0的子矩阵的最大面积.
T2:给出一个N行的,第I行有n+1-i的倒三角形,从中选取m个数,只有当前数的左上角和右上角都被选是才能选当前数,求选的数字的最大和
T3:给一个有向无环图,求任意两点间距离除以边数的最小值.
Sol:
T1:n^2枚举行的两端,然后用处理出当前列的前缀和,只有Sum[i]-Sum[j]>0时j+1~i才满足要求 并且要求i-j最大.我们把它按照数值排序,注意Sum[0]也算,排序后从0扫到n就可以得到最小的Id值,每次更新最小的Id,和最长的距离就可以了.
T2:斜着进行DP,第一个斜行长度为n,第n个斜行长度为1,刷了改行个斜行长度为K,那么前一行长度要小于等于K+1。最后输出Max(F[n][0][m],F[n][1][m]) STD的做法奥妙重重.
T3.直接Floyd但是要记录边长的Floyd,暴力枚举就可以了.
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 #define LL long long 6 using namespace std; 7 const LL Maxn=210; 8 const LL Inf=(LL)1<<60; 9 LL a[Maxn][Maxn],Sum[Maxn][Maxn],n,m,Ans; 10 struct Node{LL v,id;}S[Maxn]; 11 inline LL Max(LL x,LL y) {return x>y?x:y;} 12 inline LL Min(LL x,LL y) {return x>y?y:x;} 13 inline bool cmp(Node A,Node B) 14 { 15 if (A.v==B.v) return A.id>B.id; 16 return A.v<B.v; 17 } 18 int main() 19 { 20 scanf("%lld%lld",&n,&m); 21 for (LL i=1;i<=n;i++) 22 { 23 Sum[i][0]=0; 24 for (LL j=1;j<=m;j++) scanf("%lld",&a[i][j]),Sum[i][j]=Sum[i][j-1]+a[i][j]; 25 } 26 Ans=0; 27 for (LL i=1;i<=m;i++) 28 { 29 30 for (LL j=i;j<=m;j++) 31 { 32 S[0].v=0; S[0].id=0; 33 for (LL k=1;k<=n;k++) S[k].v=S[k-1].v+(Sum[k][j]-Sum[k][i-1]),S[k].id=k; 34 sort(S,S+n+1,cmp); LL Mx=0,Mn=Inf; 35 for (LL k=0;k<=n;k++) 36 { 37 Mn=Min(Mn,S[k].id); 38 Mx=Max(Mx,S[k].id-Mn); 39 } 40 Ans=Max(Ans,Mx*(j-i+1)); 41 } 42 } 43 printf("%lld\n",Ans); 44 return 0; 45 }
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 using namespace std; 6 int a[60][60],Sum[60][60],F[60][60][600],n,m; 7 inline int Max(int x,int y) {return x>y?x:y;} 8 int main() 9 { 10 scanf("%d%d",&n,&m); 11 for (int i=1;i<=n;i++) 12 for (int j=1;j<=n-i+1;j++) scanf("%d",&a[i][j]); 13 for (int i=1;i<=n;i++) 14 for (int j=1;j<=n-i+1;j++) Sum[j][i]=Sum[j-1][i]+a[j][i]; 15 16 for (int i=1;i<=n;i++) 17 for (int j=0;j<=n-i+1;j++) 18 for (int k=0;k<=j+1;k++) 19 for (int s=j;s<=m;s++) 20 F[i][j][s]=Max(F[i][j][s],F[i-1][k][s-j]+Sum[j][i]); 21 22 printf("%d\n",Max(F[n][0][m],F[n][1][m])); 23 return 0; 24 }
1 #include <cstdio> 2 const int Inf=0x3f3f3f3f; 3 int F[55][55][55],n,m,q,u,v,w,G[55][55]; 4 inline int Min(int x,int y) {return x>y?y:x;} 5 int main() 6 { 7 scanf("%d%d",&n,&m); 8 for (int i=1;i<=n;i++) 9 for (int j=1;j<=n;j++) 10 for (int k=0;k<=n;k++) F[i][j][k]=Inf; 11 for (int i=1;i<=n;i++) F[i][i][0]=0; 12 for (int i=1;i<=m;i++) 13 scanf("%d%d%d",&u,&v,&w),F[u][v][1]=Min(F[u][v][1],w); 14 15 for (int k=1;k<=n;k++) 16 for (int i=1;i<=n;i++) 17 for (int j=1;j<=n;j++) 18 for (int p=1;p<=n;p++) 19 F[i][j][p]=Min(F[i][j][p],F[i][k][p-1]+F[k][j][1]); 20 scanf("%d",&q); 21 for (int i=1;i<=q;i++) 22 { 23 scanf("%d%d",&u,&v); double Ans=(double)Inf; 24 if (G[u][v]!=0) Ans=G[u][v]; else 25 { 26 for (int j=1;j<=n;j++) 27 if (F[u][v][j]<Inf && ((double)(F[u][v][j])/(double)(j))<Ans) Ans=((double)(F[u][v][j])/(double)(j)); 28 } 29 G[u][v]=Ans; 30 if (Ans>=Inf) puts("OMG!"); else printf("%0.3lf\n",Ans); 31 } 32 return 0; 33 }
7.11
T1. 注意到我们并不需要求出具体的周期是多少。
如果𝐴是周期,𝐵是周期,那么𝐴𝐵也是周期。
所以只需要枚举𝜑(𝑁)/𝑓 作为周期,其中𝑓是𝜑(𝑁)的所有质因子。
T2.因为最终魔法值是对2取模的,于是所有非对角线上的元素都可以忽略。因为每次修改操作都一定更改了一个对角线上的元素,所以连后面的操 作数𝑖都是没用的了。
T3.𝑓[𝑖][𝑎][b][𝑐]表示已经转移到i行,有a列有1个挖掘机,有b列有2个挖掘 机,有c列有3个挖掘机时,方案数量。转移超级复杂。类似于BZOJ 1801。
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <vector> 5 #define pb push_back 6 #define LL long long 7 using namespace std; 8 LL n,Q,x,P; 9 vector<LL> V; 10 inline LL Gcd(LL a,LL b) {return b==0?a:Gcd(b,a%b);} 11 inline LL Get_Phi(LL x) 12 { 13 LL Ret=x,t=x; 14 for (LL i=2;i*i<=t;i++) 15 if (x%i==0) 16 { 17 Ret=Ret/i*(i-1); 18 while (x%i==0) x/=i; 19 } 20 if (x!=1) Ret=Ret/x*(x-1); 21 return Ret; 22 } 23 inline void Frac(LL x) 24 { 25 for (LL i=2;i*i<=x;i++) 26 if (x%i==0) 27 { 28 V.pb(i),V.pb(x/i); 29 while (x%i==0) x/=i; 30 } 31 if (x>1) V.pb(x); 32 } 33 inline LL Mul(LL x,LL y) 34 { 35 LL Ret=0; 36 while (true) 37 { 38 if (y&1) Ret=(Ret+x)%n; 39 x=(x+x)%n; y>>=1; if (!y) break; 40 } 41 return Ret; 42 } 43 inline LL Pow(LL x,LL y) 44 { 45 LL Ret=1; 46 while (true) 47 { 48 if (y&1) Ret=Mul(Ret,x)%n; 49 x=Mul(x,x)%n; y>>=1; if (!y) break; 50 } 51 return Ret; 52 } 53 54 int main() 55 { 56 // freopen("A.in","r",stdin); 57 // freopen("A.out","w",stdout); 58 scanf("%lld%lld",&n,&Q); 59 LL T=Get_Phi(n); V.clear(); 60 Frac(T); 61 62 for (LL i=1;i<=Q;i++) 63 { 64 scanf("%lld",&P); 65 if (Gcd(P,n)!=1) {puts("No"); continue;} 66 bool flag=true; 67 for (LL j=0;j<V.size();j++) 68 if (Pow(P,T/V[j])==1) 69 { 70 flag=false; 71 break; 72 } 73 if (flag) puts("Yes"); else puts("No"); 74 } 75 return 0; 76 }
1 #include<cstdio> 2 int n,Q,Ans,x; 3 4 int main() 5 { 6 scanf("%d",&n); 7 for (int i=1;i<=n;i++) 8 for (int j=1;j<=n;j++) 9 { 10 scanf("%d",&x); 11 if (i==j) Ans^=x; 12 } 13 scanf("%d",&Q); 14 for(int i=1;i<=Q;++i) 15 { 16 char ch=getchar(); 17 while(ch!='A' && ch!='B' && ch!='C') ch=getchar(); 18 if(ch=='C') printf("%d\n",Ans); 19 else scanf("%d",&x),Ans^=1; 20 } 21 return 0; 22 } 23
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 #define LL long long 6 using namespace std; 7 const LL Mod=19890604; 8 LL F[2][65][65][65],n,m,Ans,Cur,Pre; 9 inline LL C(LL x,LL y) 10 { 11 if (y==2) return (x*(x-1))/2; 12 if (y==3) return (x*(x-1)*(x-2))/6; 13 } 14 int main() 15 { 16 scanf("%lld%lld",&n,&m); 17 F[0][0][0][0]=1; Cur=0; 18 for (LL i=1;i<=n;i++) 19 { 20 Pre=Cur; Cur=Cur^1; 21 for (LL j=0;j<=m;j++) 22 for (LL k=0;j+k<=m;k++) 23 for (LL l=0;j+k+l<=m;l++) 24 { 25 // Put_Zero 26 F[Cur][j][k][l]=F[Pre][j][k][l]; 27 28 // Put_One 29 if (j>=1) F[Cur][j][k][l]=(F[Cur][j][k][l]+F[Pre][j-1][k][l]*(m-(j-1)-k-l))%Mod; 30 if (k>=1 && j<=m-1) F[Cur][j][k][l]=(F[Cur][j][k][l]+F[Pre][j+1][k-1][l]*(j+1))%Mod; 31 if (l>=1 && k<=m-1) F[Cur][j][k][l]=(F[Cur][j][k][l]+F[Pre][j][k+1][l-1]*(k+1))%Mod; 32 33 // Put_Two 34 if (j>=2) F[Cur][j][k][l]=(F[Cur][j][k][l]+F[Pre][j-2][k][l]*C(m-(j-2)-k-l,2))%Mod; 35 if (k>=2 && j<=m-2) F[Cur][j][k][l]=(F[Cur][j][k][l]+F[Pre][j+2][k-2][l]*C(j+2,2))%Mod; 36 if (l>=2 && k<=m-2) F[Cur][j][k][l]=(F[Cur][j][k][l]+F[Pre][j][k+2][l-2]*C(k+2,2))%Mod; 37 if (k>=1) F[Cur][j][k][l]=(F[Cur][j][k][l]+F[Pre][j][k-1][l]*j*(m-j-(k-1)-l))%Mod; 38 if (l>=1 && j<=m-1) F[Cur][j][k][l]=(F[Cur][j][k][l]+F[Pre][j+1][k][l-1]*k*(j+1))%Mod; 39 if (j>=1 && k<=m-1 && l>=1) F[Cur][j][k][l]=(F[Cur][j][k][l]+F[Pre][j-1][k+1][l-1]*(m-(j-1)-(k+1)-(l-1))*(k+1))%Mod; 40 41 // Put_Three 42 if (j>=3) F[Cur][j][k][l]=(F[Cur][j][k][l]+F[Pre][j-3][k][l]*C(m-(j-3)-k-l,3))%Mod; 43 if (k>=3 && j<=m-3) F[Cur][j][k][l]=(F[Cur][j][k][l]+F[Pre][j+3][k-3][l]*C(j+3,3))%Mod; 44 if (l>=3 && k<=m-3) F[Cur][j][k][l]=(F[Cur][j][k][l]+F[Pre][j][k+3][l-3]*C(k+3,3))%Mod; 45 if (j>=1 && k>=1) F[Cur][j][k][l]=(F[Cur][j][k][l]+F[Pre][j-1][k-1][l]*C(m-(j-1)-(k-1)-l,2)*(j-1))%Mod; 46 if (j>=2 && k<=m-1 && l>=1) F[Cur][j][k][l]=(F[Cur][j][k][l]+F[Pre][j-2][k+1][l-1]*C(m-(j-2)-(k+1)-(l-1),2)*(k+1))%Mod; 47 if (j<=m-2 && k>=2) F[Cur][j][k][l]=(F[Cur][j][k][l]+F[Pre][j+1][k-2][l]*C(j+1,2)*(m-(j+1)-(k-2)-l))%Mod; 48 if (j<=m-2 && k>=1 && l>=1) F[Cur][j][k][l]=(F[Cur][j][k][l]+F[Pre][j+2][k-1][l-1]*C(j+2,2)*(k-1))%Mod; 49 if (j>=1 && k<=m-2 && l>=2) F[Cur][j][k][l]=(F[Cur][j][k][l]+F[Pre][j-1][k+2][l-2]*(m-(j-1)-(k+2)-(l-2))*C(k+2,2))%Mod; 50 if (j<=m-1 && k<=m-1 && l>=2) F[Cur][j][k][l]=(F[Cur][j][k][l]+F[Pre][j+1][k+1][l-2]*(j+1)*C(k+1,2))%Mod; 51 if (l>=1) F[Cur][j][k][l]=(F[Cur][j][k][l]+F[Pre][j][k][l-1]*(m-j-k-(l-1))*j*k)%Mod; 52 } 53 } 54 for (LL i=0;i<=m;i++) 55 for (LL j=0;i+j<=m;j++) 56 for (LL k=0;i+j+k<=m;k++) Ans=(Ans+F[Cur][i][j][k])%Mod; 57 printf("%lld\n",Ans); 58 return 0; 59 }
7.12
T1:奥妙重重
T2:考虑对线路设点,则对线路中每个城市连一条边权为w[i][j]的边,再跑最短路。将两条线路i,j所有交点的w[i][a] + w[j][a] 之和取最小值作为i, j的边,然后跑floyd即可,询问时将两点所在线路枚举取最小值即可。复杂度O(m^3 + m * l[i] + T * m^2)。
T3.用线段树维护DP
1 #include <cstdio> 2 #define LL long long 3 LL n,k; 4 int main() 5 { 6 while (scanf("%lld%lld",&n,&k)!=EOF) 7 { 8 if (n==0 && k==0) break; 9 if ((n*k)&1) puts("Y"); else puts("N"); 10 } 11 return 0; 12 }
1 #include <cstdio> 2 #include <cstring> 3 #include <cassert> 4 const int Maxn=400100; 5 const int Maxm=310; 6 const int Inf=0x3f3f3f3f; 7 struct EDGE{int to,next,w;}edge[1100100]; 8 int n,m,u,v,F[Maxm][Maxm],W[Maxm][200100],head[200100],a[200100],cnt,Ans,l,x,y,tmp; 9 inline void Add(int u,int v,int w) {edge[cnt].to=v;edge[cnt].next=head[u];edge[cnt].w=w; head[u]=cnt++;} 10 inline int Min(int x,int y) {return x>y?y:x;} 11 int main() 12 { 13 scanf("%d%d",&n,&m); 14 memset(head,-1,sizeof(head)); 15 for (int i=1;i<=m;i++) 16 { 17 scanf("%d",&l); tmp=0; 18 for (int j=1;j<=l;j++) 19 { 20 scanf("%d%d",&x,&y); 21 if (W[i][x]) W[i][x]=Min(W[i][x],y); else W[i][x]=y,a[++tmp]=x; 22 } 23 for (int j=1;j<=tmp;j++) 24 { 25 Add(n+i,a[j],W[i][a[j]]),Add(a[j],n+i,W[i][a[j]]); 26 } 27 } 28 for (int i=1;i<=m;i++) for (int j=1;j<=m;j++) if (i!=j) F[i][j]=Inf; 29 for (int i=1;i<=n;i++) 30 for (int j=head[i];j!=-1;j=edge[j].next) 31 for (int k=edge[j].next;k!=-1;k=edge[k].next) 32 F[edge[j].to-n][edge[k].to-n]=F[edge[k].to-n][edge[j].to-n]=Min(F[edge[j].to-n][edge[k].to-n],edge[j].w+edge[k].w); 33 34 for (int k=1;k<=m;k++) 35 for (int i=1;i<=m;i++) 36 for (int j=1;j<=m;j++) F[i][j]=Min(F[i][j],F[i][k]+F[k][j]); 37 38 while (scanf("%d%d",&u,&v)!=EOF) 39 { 40 if (u==0 && v==0) break; 41 if (u==v) 42 { 43 puts("0"); 44 continue; 45 } 46 Ans=Inf; 47 for (int i=head[u];i!=-1;i=edge[i].next) 48 for (int j=head[v];j!=-1;j=edge[j].next) 49 Ans=Min(Ans,F[edge[i].to-n][edge[j].to-n]+edge[i].w+edge[j].w); 50 if (Ans==Inf) puts("-1"); else printf("%d\n",Ans); 51 } 52 return 0; 53 }
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 const int maxn=2e5+10,inf=1e9,maxp=8e5; 5 using namespace std; 6 inline int read(){ 7 int tmp=0;char c=getchar(); 8 while(c<'0'||c>'9')c=getchar(); 9 while(c>='0'&&c<='9')tmp=tmp*10+c-'0',c=getchar(); 10 return tmp; 11 } 12 int n,l,c,x[maxn],t[maxn],dp[maxn]; 13 deque<int> q[maxn]; 14 struct SGT{ 15 int val[maxp]; 16 void modify(int p,int v,int k,int l,int r){ 17 if(l==r){val[k]=v;return;} 18 int m=(l+r)>>1; 19 if(p<=m)modify(p,v,k<<1,l,m); 20 else modify(p,v,k<<1|1,m+1,r); 21 val[k]=max(val[k<<1],val[k<<1|1]); 22 } 23 int getmax(int p,int k,int l,int r){ 24 if(r<=p)return val[k]; 25 int m=(l+r)>>1; 26 if(p<=m)return getmax(p,k<<1,l,m); 27 return max(getmax(p,k<<1,l,m),getmax(p,k<<1|1,m+1,r)); 28 } 29 }T; 30 int work(){ 31 dp[1]=l-t[1];q[1].push_back(1);T.modify(1,dp[1],1,1,n); 32 for(int i=2;i<=n;++i){ 33 if(i-c>0){ 34 int t=i-c,p=x[1]-x[t]+t; 35 if(p>0&&q[p].size()&&i-q[p].front()>=c){ 36 T.modify(p,0,1,1,n);q[p].pop_front(); 37 if(q[p].size())T.modify(p,dp[q[p].front()],1,1,n); 38 } 39 } 40 int p=x[1]-x[i]+i; 41 if(p>0){ 42 dp[i]=T.getmax(p,1,1,n)-t[i]; 43 while(q[p].size()&&dp[i]>dp[q[p].back()]){ 44 if(q[p].size()==1)T.modify(p,0,1,1,n); 45 q[p].pop_back(); 46 } 47 q[p].push_back(i); 48 if(q[p].size()==1)T.modify(p,dp[i],1,1,n); 49 } 50 } 51 return dp[n]<=0?-1:dp[n]; 52 } 53 54 int main(){ 55 scanf("%d%d%d",&n,&c,&l); 56 for(int i=1;i<=n;++i)x[i]=read(),t[i]=read(); 57 printf("%d\n",work()); 58 59 return 0; 60 }
7.13
T1:首先先求出gcd(a,b)将a/b约分。
一位一位的转换k进制,记录一个last数组,last[i]代表i值上一次出现的位置。
如果某一次计算某一位的值为0就直接输出。
T2:用堆维护最大的范围,好神的一道题
T3:类似于拓扑排序,对于环特判一下
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 #define LL long long 6 const int Maxn=100010; 7 LL vis[Maxn],p,q,k,KASE; 8 int main() 9 { 10 scanf("%lld",&KASE); 11 for (int Kase=1;Kase<=KASE;Kase++) 12 { 13 scanf("%lld%lld%lld",&p,&q,&k); 14 memset(vis,0,sizeof(vis)); 15 p=p%q; vis[p]=1; 16 if (p==0) {puts("0 0"); continue;} 17 for (LL i=2;;i++) 18 { 19 p=(p*k)%q; 20 if (p==0) {printf("%lld 0\n",i-1); break;} 21 if (vis[p]) {printf("%lld %lld\n",vis[p]-1,i-vis[p]); break;} 22 vis[p]=i; 23 } 24 } 25 return 0; 26 } 27
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 #include <map> 6 #include <queue> 7 #define fi first 8 using namespace std; 9 const int Maxn=1000100; 10 int n,m,Pos[Maxn],a,b; 11 map<int,int> T; 12 struct Info 13 { 14 int Pos,Len; 15 Info (int _Pos=0,int _Len=0){Pos=_Pos,Len=_Len;} 16 }; 17 inline bool operator == (Info A,Info B) {return A.Pos==B.Pos && A.Len==B.Len;} 18 inline bool operator < (Info A,Info B) {return A.Len<B.Len || (A.Len==B.Len && A.Pos>B.Pos);} 19 struct HEAP 20 { 21 priority_queue<Info> A,B; 22 inline int Size() {return A.size()-B.size();} 23 inline void Update() {while (B.size() && A.top()==B.top()) A.pop(),B.pop();} 24 inline void Pop() {Update(); A.pop();} 25 inline void Push(Info x) {A.push(x);} 26 inline void Del(Info x) {B.push(x);} 27 inline Info Top() {Update(); return A.top();} 28 }Heap; 29 30 int main() 31 { 32 scanf("%d%d",&n,&m); 33 Heap.Push(Info(1,n)); 34 for (int i=1;i<=m;i++) 35 { 36 scanf("%d%d",&a,&b); 37 if (a==1) 38 { 39 int p=Heap.Top().Pos; Heap.Pop(); 40 printf("%d\n",p); 41 Pos[b]=p; T[p]=b; 42 map<int,int>::iterator it=T.find(p); 43 if (it==T.begin()) Heap.Push(Info(1,p-1)); 44 else 45 { 46 int r=it->fi; 47 int l=(--it)->fi; 48 Heap.Push(Info((l+r)>>1,(r-l)>>1)); 49 } 50 it=T.find(p); 51 if (it==--T.end()) Heap.Push(Info(n,n-p)); 52 else 53 { 54 int l=it->fi; 55 int r=(++it)->fi; 56 Heap.Push(Info((l+r)>>1,(r-l)>>1)); 57 } 58 } 59 60 if (a==2) 61 { 62 int p=Pos[b],ll,rr; 63 map<int,int>::iterator it=T.find(p); 64 if (it==T.begin()) Heap.Del(Info(1,p-1)),ll=0; 65 else 66 { 67 int r=it->fi; 68 int l=(--it)->fi; 69 ll=l; 70 Heap.Del(Info((l+r)>>1,(r-l)>>1)); 71 } 72 it=T.find(p); 73 if (it==--T.end()) Heap.Del(Info(n,n-p)),rr=0; 74 else 75 { 76 int l=it->fi; 77 int r=(++it)->fi; 78 rr=r; 79 Heap.Del(Info((l+r)>>1,(r-l)>>1)); 80 } 81 it=T.find(p); 82 T.erase(it); 83 if (ll && rr) Heap.Push(Info((ll+rr)>>1,(rr-ll)>>1)); 84 else if (ll) Heap.Push(Info(n,n-ll)); 85 else if (rr) Heap.Push(Info(1,rr-1)); 86 else Heap.Push(Info(1,n)); 87 88 } 89 } 90 return 0; 91 } 92
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 using namespace std; 6 const int Maxn=100100; 7 int a[Maxn],In[Maxn],Q[Maxn],n,Ans; 8 bool vis[Maxn]; 9 inline void Sort() 10 { 11 int l,r; l=1,r=0; 12 for (int i=1;i<=n;i++) if (In[i]==0) Q[++r]=i,vis[i]=true; 13 while (l<=r) 14 { 15 int u=Q[l++]; 16 if (!vis[a[u]]) 17 { 18 Ans++; vis[a[u]]=true; In[a[a[u]]]--; 19 if (!vis[a[a[u]]] && !In[a[a[u]]]) 20 { 21 vis[a[a[u]]]=true; 22 Q[++r]=a[a[u]]; 23 } 24 } 25 } 26 27 for (int i=1;i<=n;i++) 28 if (!vis[i]) 29 { 30 int t=i,Ret=0; 31 while (!vis[t]) Ret++,vis[t]=true,t=a[t]; 32 Ans+=(Ret>>1); 33 } 34 } 35 int main() 36 { 37 scanf("%d",&n); 38 for (int i=1;i<=n;i++) 39 { 40 scanf("%d",&a[i]); 41 In[a[i]]++; 42 } 43 Sort(); 44 printf("%d\n",Ans); 45 return 0; 46 } 47
7.14
T1:差分一下,每次只会修改一个..
T2:组合数取模
T3:不会..
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 using namespace std; 6 const int Maxn=400010; 7 const int Inf=0x3f3f3f3f; 8 struct EDGE{int to,next;}edge[Maxn<<1]; 9 int head[Maxn],cnt,a[Maxn],s[Maxn],zhouzx,Pre[Maxn],n,q,u,v; 10 inline void Add(int u,int v) {edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++;} 11 void Dfs(int u) 12 { 13 for (int i=head[u];i!=-1;i=edge[i].next) 14 a[edge[i].to]=s[edge[i].to]-s[u],Dfs(edge[i].to); 15 } 16 int main() 17 { 18 // freopen("salaryman.in","r",stdin); 19 // freopen("salaryman.out","w",stdout); 20 scanf("%d%d",&n,&q); Pre[1]=0; 21 memset(head,-1,sizeof(head)); 22 for (int i=2;i<=n;i++) 23 { 24 scanf("%d",&u); 25 Pre[i]=u; Add(u,i); 26 } 27 for (int i=1;i<=n;i++) scanf("%d",&s[i]); 28 Dfs(1); 29 a[1]=-Inf; 30 for (int i=1;i<=n;i++) if (a[i]>0) zhouzx++; 31 32 for (int i=1;i<=q;i++) 33 { 34 scanf("%d%d",&u,&v); 35 if (a[u]<=0 && a[u]+v>0) zhouzx++; 36 if (a[u]>0 && a[u]+v<=0) zhouzx--; 37 a[u]=a[u]+v; 38 if (zhouzx==0) puts("GOOD"); 39 if (zhouzx>0) puts("BAD"); 40 41 } 42 return 0; 43 }
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 #include <cassert> 6 #define LL long long 7 using namespace std; 8 const LL Maxn=100100; 9 LL n,k,p,a[Maxn],Mod[Maxn],cnt,Ans[Maxn],Prime[Maxn]; 10 inline void Get_Fac(LL o) 11 { 12 for (LL i=2;i*i<=o;i++) 13 if (o%i==0) 14 { 15 cnt++; 16 Mod[cnt]=1; 17 Prime[cnt]=i; 18 while (o%i==0) 19 { 20 Mod[cnt]*=i; 21 o/=i; 22 } 23 } 24 if (o>1) 25 { 26 Mod[++cnt]=o; 27 Prime[cnt]=o; 28 } 29 } 30 inline LL Pow(LL Base,LL Exp,LL Mod) 31 { 32 LL Ans=1; Base%=Mod; 33 while (Exp) 34 { 35 if (Exp&1) Ans=(Ans*Base)%Mod; 36 Base=(Base*Base)%Mod; Exp>>=1; 37 } 38 return Ans; 39 } 40 inline LL Extend_Gcd(LL a,LL b,LL &x,LL &y) 41 { 42 if (b==0) 43 { 44 x=1,y=0; 45 return a; 46 } 47 LL Ret=Extend_Gcd(b,a%b,y,x); 48 y-=a/b*x; 49 return Ret; 50 } 51 52 inline LL Rev(LL a,LL P) 53 { 54 LL x,y; 55 LL t=Extend_Gcd(a,P,x,y); 56 return (x+P)%P; 57 } 58 inline LL CRT() 59 { 60 LL Ret=0; 61 for (LL i=1;i<=cnt;i++) 62 { 63 LL Tmp=(p/Mod[i])%p; 64 Ret=(Ret+(Tmp*Rev(Tmp,Mod[i]))%p*Ans[i])%p; 65 } 66 return Ret; 67 } 68 inline void Fac(LL n,LL q,LL &t,LL &u) 69 { 70 while (n%Prime[q]==0) u++,n/=Prime[q]; 71 t=n; 72 } 73 inline LL Calc(LL q) 74 { 75 LL Ret1=0,Begin1=1,tt,tu,u=0; 76 for (LL i=k;i<=n;i++) 77 { 78 Ret1=(Ret1+a[i]*Begin1%Mod[q]*Pow(Prime[q],u,Mod[q]))%Mod[q]; // C(i-1,k-1) 79 tt=1,tu=0; 80 Fac(i,q,tt,tu); 81 Begin1=(Begin1*tt)%Mod[q]; u+=tu; 82 tt=1,tu=0; 83 Fac(i-k+1,q,tt,tu); 84 Begin1=(Begin1*Rev(tt,Mod[q]))%Mod[q]; u-=tu; 85 } 86 u=0; 87 LL Ret2=0,Begin2=1; 88 for (LL i=n-k+1;i>=1;i--) 89 { 90 Ret2=(Ret2+a[i]*Begin2%Mod[q]*Pow(Prime[q],u,Mod[q]))%Mod[q]; //C(n-i,k-1); 91 tt=1,tu=0; 92 Fac(n-i+1,q,tt,tu); 93 Begin2=(Begin2*tt)%Mod[q]; u+=tu; 94 tt=1,tu=0; 95 Fac(n-k-i+2,q,tt,tu); 96 Begin2=(Begin2*Rev(tt,Mod[q]))%Mod[q]; u-=tu; 97 } 98 return ((Ret1-Ret2)%Mod[q]+Mod[q])%Mod[q]; 99 } 100 inline LL Work() 101 { 102 for (LL i=1;i<=cnt;i++) Ans[i]=Calc(i); 103 return CRT(); 104 } 105 int main() 106 { 107 scanf("%lld%lld%lld",&n,&k,&p); 108 for (LL i=1;i<=n;i++) scanf("%lld",&a[i]); 109 sort(a+1,a+n+1); 110 Get_Fac(p); 111 printf("%lld\n",Work()); 112 return 0; 113 }
7.16
T1:模拟
T2:用类似于高精度的方法
T3:最短路..
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 #define LL long long 6 using namespace std; 7 const LL Maxn=200100; 8 struct Info{LL a,b;}C[Maxn]; 9 LL n,Ans=0; 10 inline bool cmp(Info A,Info B) {return A.b<B.b;} 11 int main() 12 { 13 scanf("%lld",&n); 14 for (LL i=1;i<=n;i++) scanf("%lld%lld",&C[i].a,&C[i].b); 15 sort(C+1,C+n+1,cmp); 16 LL i=1; 17 while (true) 18 { 19 LL Ret=C[i].a; 20 while (C[i].b==C[i+1].b) 21 { 22 Ret+=C[i+1].a; 23 i++; 24 } 25 Ans=Ans+Ret*Ret; i++; 26 if (i==n+1) break; 27 } 28 printf("%lld\n",Ans); 29 return 0; 30 } 31
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 #include <cassert> 6 using namespace std; 7 const int Maxn=2050; 8 const int Mod=10007; 9 struct Info{int Len,a[Maxn];}Tmp; 10 char Str[Maxn]; 11 inline int Max(int x,int y) {return x>y?x:y;} 12 inline Info operator + (Info A,Info B) 13 { 14 Info C; C.Len=Max(A.Len,B.Len); memset(C.a,0,sizeof(C.a)); 15 for (int i=0;i<=C.Len;i++) C.a[i]=(A.a[i]+B.a[i])%Mod; 16 while (C.Len && !C.a[C.Len]) C.Len--; 17 return C; 18 } 19 inline Info operator - (Info A,Info B) 20 { 21 Info C; C.Len=Max(A.Len,B.Len); memset(C.a,0,sizeof(C.a)); 22 for (int i=0;i<=C.Len;i++) C.a[i]=(A.a[i]-B.a[i]+Mod)%Mod; 23 while (C.Len && !C.a[C.Len]) C.Len--; 24 return C; 25 } 26 inline Info operator * (Info A,Info B) 27 { 28 Info C; C.Len=A.Len+B.Len; memset(C.a,0,sizeof(C.a)); 29 for (int i=0;i<=A.Len;i++) 30 for (int j=0;j<=B.Len;j++) 31 C.a[i+j]=(C.a[i+j]+A.a[i]*B.a[j])%Mod; 32 while (C.Len && !C.a[C.Len]) C.Len--; 33 return C; 34 } 35 inline Info Factor(int l,int r) 36 { 37 38 int tot=0; 39 for (int i=l;i<=r;i++) 40 { 41 if (Str[i]=='(') tot++; 42 if (Str[i]==')') tot--; 43 if (!tot && Str[i]=='+') 44 return Factor(l,i-1)+Factor(i+1,r); 45 } 46 for (int i=r;i>=l;i--) 47 { 48 if (Str[i]=='(') tot++; 49 if (Str[i]==')') tot--; 50 if (!tot && Str[i]=='-') 51 return Factor(l,i-1)-Factor(i+1,r); 52 } 53 for (int i=l;i<=r;i++) 54 { 55 if (Str[i]=='(') tot++; 56 if (Str[i]==')') tot--; 57 if (!tot && Str[i]=='*') 58 return Factor(l,i-1)*Factor(i+1,r); 59 } 60 if (Str[l]=='(' && Str[r]==')') return Factor(l+1,r-1); 61 if (l==r && Str[l]=='x') 62 { 63 Tmp.Len=1; memset(Tmp.a,0,sizeof(Tmp.a)); Tmp.a[0]=0; Tmp.a[1]=1; 64 return Tmp; 65 } 66 Tmp.Len=0; memset(Tmp.a,0,sizeof(Tmp.a)); 67 for (int i=l;i<=r;i++) 68 { 69 Tmp.a[0]*=10; 70 Tmp.a[0]+=Str[i]-'0'; 71 } 72 return Tmp; 73 } 74 inline void Print(Info Ans) 75 { 76 printf("%d\n",Ans.Len); 77 for (int i=0;i<=Ans.Len;i++) printf("%d\n",Ans.a[i]); 78 } 79 int main() 80 { 81 scanf("%s",Str+1); int n=strlen(Str+1); 82 Print(Factor(1,n)); 83 return 0; 84 }
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int N = 3050; 7 const int M = 500050; 8 const int inf = 987654321; 9 int n,m,q; 10 struct Edge 11 { 12 int u,v,w; 13 }xu[M]; 14 int point[N],to[M],Next[M],val[M]; 15 int dui[N],mina[N],minb[N],top,tail; 16 bool indui[N]; 17 void MakeMinLen(int x[]) 18 { 19 int i; 20 dui[1]=1; 21 top=0;tail=1; 22 indui[1]=1; 23 for(i=1;i<=n;i++) 24 x[i]=inf; 25 x[1]=0; 26 while(top^tail) 27 { 28 top++; 29 if(top==N) 30 top=0; 31 int now=dui[top]; 32 int then=point[now]; 33 indui[now]=0; 34 while(then) 35 { 36 int tox=to[then]; 37 if(x[tox]>x[now]+val[then]) 38 { 39 x[tox]=x[now]+val[then]; 40 if(!indui[tox]) 41 { 42 indui[tox]=1; 43 tail++; 44 if(tail==N) 45 tail=0; 46 dui[tail]=tox; 47 } 48 } 49 then=Next[then]; 50 } 51 } 52 } 53 void InitGraph() 54 { 55 int i; 56 scanf("%d%d",&n,&m); 57 for(i=1;i<=m;i++) 58 scanf("%d%d%d",&xu[i].u,&xu[i].v,&xu[i].w); 59 memset(point,0,sizeof point); 60 for(i=1;i<=m;i++) 61 { 62 Next[i]=point[xu[i].v]; 63 point[xu[i].v]=i; 64 to[i]=xu[i].u; 65 val[i]=xu[i].w; 66 } 67 MakeMinLen(mina); 68 memset(point,0,sizeof point); 69 for(i=1;i<=m;i++) 70 { 71 Next[i]=point[xu[i].u]; 72 point[xu[i].u]=i; 73 to[i]=xu[i].v; 74 val[i]=xu[i].w; 75 } 76 MakeMinLen(minb); 77 } 78 void MakeAns() 79 { 80 scanf("%d",&q); 81 while(q--) 82 { 83 int a,b; 84 scanf("%d%d",&a,&b); 85 int res=mina[a]+minb[b]; 86 if(res>=inf) 87 res=-1; 88 printf("%d\n",res); 89 } 90 } 91 int main() 92 { 93 // freopen("production.in","r",stdin); 94 // freopen("production.out","w",stdout); 95 InitGraph(); 96 MakeAns(); 97 return 0; 98 }
7.17
难以描述奥妙重重的一套题,见Sol把
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 #define LL long long 6 using namespace std; 7 const LL Mod=905229641; 8 const LL Maxm=110; 9 LL Fac[Maxm],Rev[Maxm],n,m,F[Maxm][Maxm*Maxm]; 10 inline LL Pow(LL Base,LL Exp) 11 { 12 LL Ret=1; 13 while (Exp) 14 { 15 if (Exp&1) Ret=(Ret*Base)%Mod; 16 Base=(Base*Base)%Mod; Exp>>=1; 17 } 18 return Ret; 19 } 20 inline LL C(LL n,LL m) 21 { 22 LL Ret=1; 23 for (LL i=1;i<=m;i++) Ret=(Ret*((n-i+1)%Mod))%Mod; 24 for (LL i=1;i<=m;i++) Ret=(Ret*Rev[i])%Mod; 25 return Ret; 26 } 27 inline LL Min(LL x,LL y) {return x>y?y:x;} 28 int main() 29 { 30 scanf("%lld%lld",&n,&m); 31 Fac[0]=1; 32 for (LL i=1;i<=m;i++) 33 Fac[i]=(Fac[i-1]*i)%Mod, 34 Rev[i]=Pow(i,Mod-2); 35 F[0][0]=1; LL w=(m*(m-1))>>1; 36 for (LL i=0;i<m;i++) 37 for (LL j=m-1;j>=0;j--) 38 for (LL k=w;k>=i;k--) 39 F[j+1][k]=(F[j+1][k]+F[j][k-i])%Mod; 40 LL Remain=n%m; 41 LL Ans=0; 42 for (LL i=1;i<=m;i++) 43 for (LL j=Remain;j<=Min(n,w);j+=m) 44 { 45 LL cnt=(n-j)/m; 46 Ans=(Ans+(F[i][j]*Fac[i])%Mod*C(cnt+i-1,i-1))%Mod; 47 } 48 printf("%lld\n",(Ans+Mod)%Mod); 49 return 0; 50 }
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 #define LL long long 6 using namespace std; 7 const LL Mod=1000000007; 8 const LL Maxn=100010; 9 const LL Inf=0x3f3f3f3f; 10 struct EDGE{LL to,next;}edge[Maxn<<1]; 11 LL head[Maxn],n,u,v,cnt,F[Maxn],G[Maxn],H[Maxn],Fs[Maxn],Hs[Maxn],Gs[Maxn],L[Maxn],R[Maxn],Q[Maxn]; 12 inline LL Min(LL x,LL y) {return x>y?y:x;} 13 inline LL Min3(LL x,LL y,LL z) {return Min(x,Min(y,z));} 14 inline void Add(LL u,LL v) {edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++;} 15 void Dfs(LL u,LL fa) 16 { 17 F[u]=1; G[u]=Inf; H[u]=0; Fs[u]=1; Hs[u]=1; Gs[u]=1; LL Sum=0,Dif=Inf; 18 for (LL i=head[u];i!=-1;i=edge[i].next) 19 { 20 if (edge[i].to==fa) continue; 21 Dfs(edge[i].to,u); 22 F[u]+=Min3(F[edge[i].to],G[edge[i].to],H[edge[i].to]); 23 H[u]+=G[edge[i].to]; 24 Sum+=Min(F[edge[i].to],G[edge[i].to]); 25 Dif=Min(Dif,F[edge[i].to]-G[edge[i].to]); 26 } 27 for (LL i=head[u];i!=-1;i=edge[i].next) 28 { 29 if (edge[i].to==fa) continue; 30 G[u]=Min(G[u],F[edge[i].to]+Sum-Min(F[edge[i].to],G[edge[i].to])); 31 } 32 33 for (LL i=head[u];i!=-1;i=edge[i].next) 34 { 35 if (edge[i].to==fa) continue; LL Tmp=0; 36 if (F[edge[i].to]==Min3(F[edge[i].to],G[edge[i].to],H[edge[i].to])) Tmp=(Tmp+Fs[edge[i].to])%Mod; 37 if (G[edge[i].to]==Min3(F[edge[i].to],G[edge[i].to],H[edge[i].to])) Tmp=(Tmp+Gs[edge[i].to])%Mod; 38 if (H[edge[i].to]==Min3(F[edge[i].to],G[edge[i].to],H[edge[i].to])) Tmp=(Tmp+Hs[edge[i].to])%Mod; 39 Fs[u]=(Fs[u]*Tmp)%Mod; 40 } 41 for (LL i=head[u];i!=-1;i=edge[i].next) 42 { 43 if (edge[i].to==fa) continue; 44 Hs[u]=(Hs[u]*Gs[edge[i].to])%Mod; 45 } 46 47 if (Dif>0) 48 { 49 LL Cnt=0; 50 for (LL i=head[u];i!=-1;i=edge[i].next) 51 { 52 if (edge[i].to==fa) continue; 53 if (F[edge[i].to]-G[edge[i].to]==Dif) Q[++Cnt]=edge[i].to; else Gs[u]=(Gs[u]*Gs[edge[i].to])%Mod; 54 } 55 L[0]=1;R[Cnt+1]=1; LL Tmp=0; 56 for (LL i=1;i<=Cnt;i++) L[i]=R[i]=Gs[Q[i]]; 57 for (LL i=1;i<=Cnt;i++) L[i]=(L[i]*L[i-1])%Mod; 58 for (LL i=Cnt;i>=1;i--) R[i]=(R[i]*R[i+1])%Mod; 59 for (LL i=1;i<=Cnt;i++) Tmp=(Tmp+((L[i-1]*R[i+1])%Mod*Fs[Q[i]])%Mod)%Mod; 60 Gs[u]=(Gs[u]*Tmp)%Mod; 61 } 62 if (Dif==0) 63 { 64 LL Tmp=1; 65 for (LL i=head[u];i!=-1;i=edge[i].next) 66 { 67 if (edge[i].to==fa) continue; 68 if (F[edge[i].to]==G[edge[i].to]) Gs[u]=(Gs[u]*(Fs[edge[i].to]+Gs[edge[i].to]))%Mod; else Gs[u]=(Gs[u]*Gs[edge[i].to])%Mod; 69 Tmp=(Tmp*Gs[edge[i].to])%Mod; 70 } 71 Gs[u]=(Gs[u]-Tmp+Mod)%Mod; 72 } 73 if (Dif<0) 74 { 75 for (LL i=head[u];i!=-1;i=edge[i].next) 76 { 77 if (edge[i].to==fa) continue; 78 if (F[edge[i].to]==G[edge[i].to]) Gs[u]=(Gs[u]*(Fs[edge[i].to]+Gs[edge[i].to]))%Mod; 79 if (F[edge[i].to]>G[edge[i].to]) Gs[u]=(Gs[u]*Gs[edge[i].to])%Mod; 80 if (F[edge[i].to]<G[edge[i].to]) Gs[u]=(Gs[u]*Fs[edge[i].to])%Mod; 81 } 82 } 83 } 84 int main() 85 { 86 scanf("%lld",&n); 87 memset(head,-1,sizeof(head)); 88 for (LL i=1;i<n;i++) 89 { 90 scanf("%lld%lld",&u,&v); 91 Add(u,v),Add(v,u); 92 } 93 Dfs(1,0); 94 printf("%lld\n",Min(F[1],G[1])); 95 LL Ret=0; 96 if (F[1]==Min(F[1],G[1])) Ret=(Ret+Fs[1])%Mod; 97 if (G[1]==Min(F[1],G[1])) Ret=(Ret+Gs[1])%Mod; 98 printf("%lld\n",Ret); 99 return 0; 100 }
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 #define LL long long 6 using namespace std; 7 const LL Maxm=1000100; 8 const LL Maxn=1010; 9 const LL Mod=1000000007; 10 const LL Inf=0x3f3f3f3f; 11 struct EDGE{LL to,next;}edge[Maxm]; 12 LL head[Maxn],cnt,n,m,a[Maxn],F[Maxn],u,v; 13 bool vis[Maxn]; 14 inline void Add(LL u,LL v) 15 {edge[cnt].to=v;edge[cnt].next=head[u];head[u]=cnt++;} 16 int main() 17 { 18 scanf("%lld%lld",&n,&m); 19 memset(head,-1,sizeof(head)); 20 for (LL i=1;i<=m;i++) 21 { 22 scanf("%lld%lld",&u,&v); 23 Add(u,v),Add(v,u); 24 } 25 for (LL i=1;i<=n;i++) 26 { 27 LL Tmp=1; 28 for (LL j=head[i];j!=-1;j=edge[j].next) if (edge[j].to>i) Tmp++; 29 for (LL j=1;;j++) 30 { 31 if (!vis[j]) Tmp--; 32 if (Tmp==0) {vis[j]=true; a[i]=j; break;} 33 } 34 } 35 a[0]=-Inf; a[n+1]=Inf-1; F[0]=1; 36 for (LL i=0;i<=n;i++) 37 { 38 LL Tmp=Inf; 39 for (LL j=i+1;j<=n+1;j++) 40 { 41 if (Tmp>a[j] && a[j]>a[i])F[j]=(F[j]+F[i])%Mod; 42 if (a[j]>a[i] && a[j]<Tmp) Tmp=a[j]; 43 } 44 } 45 printf("%lld\n",F[n+1]); 46 return 0; 47 }