2018 ACM-ICPC, Asia Shenyang Regional Contest CEJ

C. Insertion Sort

求有多少 1 到 n 的排列 满足条件将前 k 个的数排列以后 最长上升子序列长度为 n−1 以上

队友推了式子 试了下就过了

 1 #include<bits/stdc++.h>
 2 typedef long long ll;
 3 using namespace std;
 4 
 5 ll ans,n,k,p;
 6 
 7 ll PP()
 8 {
 9     ll sum=1;
10     for(int i=1;i<=k;i++)
11         sum=(sum*i)%p;
12     return sum;
13 }
14 
15 int main()
16 {
17     int T;
18     scanf("%d",&T);
19     for(int t=1;t<=T;t++)
20     {
21         ans=0;
22         printf("Case #%d: ",t);
23         scanf("%lld%lld%lld",&n,&k,&p);
24         if(k==1)
25         {
26             printf("%d\n",(n-1)*(n-1)+1);
27             continue;
28         }
29         if(k>=n)k=n;
30         ans=PP();
31         if(k==n)
32         {
33             printf("%lld\n",ans);
34             continue;
35         }
36         ans=(ans*((n-1)*(n-k)+1))%p;
37         printf("%lld\n",ans);
38     }
39 }
View Code

J. How Much Memory Your Code Is Using?

算空间 因为输入很规范 所以稍微讨论讨论就行

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 char a[100100];
 4 int l;
 5 long long fum()
 6 {
 7     long long s=0,s1=1;
 8     while(a[l]>='0'&&a[l]<='9')
 9     {
10         s+=s1*(a[l]-'0');
11         s1*=10;
12         l--;
13     }
14     return s;
15 }
16 long long work()
17 {
18     fgets(a,100001,stdin);
19     l=strlen(a)-4;
20     long long s=1;
21     if(a[l+1]==']')
22     {
23         s=fum();
24     }
25     int x=0,y=l;
26     while(a[x]!=' ')x++;
27     while(a[y]!=' ')y--;
28     if(x==y)
29     {
30         switch(a[0]-'a')
31         {
32         case 2:
33             return s;
34         case 1:
35             return s;
36         case 3:
37             return s*8;
38         case 5:
39             return s*4;
40         case 8:
41             return s*4;
42         default :
43             return s*16;
44         }
45     }
46     if(a[x+1]=='l')return s*8;
47     return s*16;
48 }
49 int main()
50 {
51     int t;
52     scanf("%d\n",&t);
53     for(int i=1;i<=t;i++)
54     {
55         long long s=0;
56         int n;
57         scanf("%d\n",&n);
58         while(n--)
59             s+=work();
60         printf("Case #%d: %lld\n",i,(s+1023)/1024);
61     }
62     return 0;
63 }
View Code

E. The Kouga Ninja Scrolls

线段树 维护每个区间最大,次大,最小,次小的x+y和x-y。注意最值和次值所属阵营要不一样。

找答案的时候 对应最大最小阵营不一样 直接减 否则 对应的最大减次小 次大减最小

注意一下x和y的范围就行

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const long long Max=6e16,Min=-6e16;
  4 struct nn
  5 {
  6     long long s;
  7     int no;
  8 }a[5];
  9 int kkk;
 10 bool cmp(nn x,nn y)
 11 {
 12     if(kkk==0)return x.s>y.s;
 13     return x.s<y.s;
 14 }
 15 struct node
 16 {
 17     nn v[8];
 18     void clear()
 19     {
 20         for(int i=0;i<8;i++)
 21         {
 22             if(i<4)v[i].s=Min;
 23             else   v[i].s=Max;
 24             v[i].no=0;
 25         }
 26     }
 27 }tree[500050];
 28 long long x[100001],y[100001];
 29 int c[100001];
 30 long long X,Y;
 31 int C;
 32 int n,m;
 33 void gx(int z,int x,int y)
 34 {
 35         for(int i=0;i<8;i+=2)
 36         {
 37             int p=i,q=i,e=1;
 38             a[0].no=0;
 39             if(i<4)a[2].s=Min,a[2].no=0,kkk=0;
 40                 else a[2].s=Max,a[2].no=0,kkk=1;
 41             while(e<=2&&(p<=i+1||q<=i+1))
 42             {
 43                 if(p<=i+1&&(q>i+1||cmp(tree[x].v[p],tree[y].v[q])))
 44                 {
 45                     if(tree[x].v[p].no!=a[e-1].no)
 46                     {
 47                         a[e]=tree[x].v[p];
 48                         e++;
 49                     }
 50                     p++;
 51                 }
 52                 else
 53                 {
 54                     if(tree[y].v[q].no!=a[e-1].no)
 55                     {
 56                         a[e]=tree[y].v[q];
 57                         e++;
 58                     }
 59                     q++;
 60                 }
 61             }
 62             tree[z].v[i]=a[1];
 63             tree[z].v[i+1]=a[2];
 64         }
 65 }
 66 void query(int l,int r,int q,int k)
 67 {
 68     if(l==r)
 69     {
 70         tree[k].clear();
 71         tree[k].v[0].s=tree[k].v[4].s=X+Y;
 72         tree[k].v[2].s=tree[k].v[6].s=X-Y;
 73         tree[k].v[0].no=tree[k].v[2].no=tree[k].v[4].no=tree[k].v[6].no=C;
 74         return;
 75     }
 76     int m=(l+r)/2;
 77     if(m>=q)query(l,m,q,2*k);
 78     else query(m+1,r,q,2*k+1);
 79     gx(k,2*k,2*k+1);
 80 }
 81 void ff(int l,int r,int x,int y,int k)
 82 {
 83     if(x<=l&&r<=y)
 84     {
 85         gx(0,0,k);
 86         return;
 87     }
 88     int m=(l+r)/2;
 89     if(m>=x)ff(l,m,x,y,2*k);
 90     if(m<y)ff(m+1,r,x,y,2*k+1);
 91 }
 92 long long findans(int l,int r)
 93 {
 94     tree[0].clear();
 95     ff(1,n,l,r,1);
 96     long long ans=0;
 97     node z=tree[0];
 98     if(z.v[0].no==z.v[4].no)ans=max(ans,max(z.v[1].s-z.v[4].s,z.v[0].s-z.v[5].s));
 99     else ans=max(ans,z.v[0].s-z.v[4].s);
100     if(z.v[2].no==z.v[6].no)ans=max(ans,max(z.v[2].s-z.v[7].s,z.v[3].s-z.v[6].s));
101     else ans=max(ans,z.v[2].s-z.v[6].s);
102     return ans;
103 }
104 int main()
105 {
106     int t,l,q;
107     scanf("%d",&t);
108     for(int i=1;i<=t;i++)
109     {
110         scanf("%d%d",&n,&m);
111         for(int j=0;j<=5*n;j++)
112             tree[j].clear();
113         for(int j=1;j<=n;j++)
114         {
115             scanf("%lld%lld%d",&x[j],&y[j],&c[j]);
116             X=x[j];Y=y[j];C=c[j];
117             query(1,n,j,1);
118         }
119         printf("Case #%d:\n",i);
120         for(int j=1;j<=m;j++)
121         {
122             scanf("%d",&l);
123             switch(l)
124             {
125             case 1:
126                 scanf("%d%lld%lld",&q,&X,&Y);
127                 X+=x[q];Y+=y[q];C=c[q];
128                 x[q]=X;y[q]=Y;
129                 //cout<<X<<" "<<Y<<endl;
130                 query(1,n,q,1);
131                 break;
132             case 2:
133                 scanf("%d%d",&q,&C);
134                 c[q]=C;X=x[q];Y=y[q];
135                 query(1,n,q,1);
136                 break;
137             case 3:
138                 scanf("%d%d",&X,&Y);
139                 printf("%lld\n",findans(X,Y));
140                 break;
141             }
142         }
143     }
144     return 0;
145 }
View Code

猜你喜欢

转载自www.cnblogs.com/hermit-lei/p/10049679.html