NOIP2016 模拟赛

Posted on 2016-09-14 10:23  yyjxx2010xyu  阅读(236)  评论(0编辑  收藏  举报

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 }
T1
 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 }
T2
 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 }
T3

 

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 }
T1
 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  
T2
 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 }
T3

 

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 }
T1
 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 }
T2
 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 }
T3

 

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                  
T1
 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  
T2
 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  
T3

 

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 }
T1
  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 }
T2

 

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  
T1
 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 }
T2
 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 }
T3

 

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 }
T1
  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 }
T2
 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 }  
T3