7.19牛客多校第二场

CD签到

我赛场上只做出K

K

一个n的排列,从1到n依次把数插入栈中,如果栈非空且栈顶大于当前数则弹掉栈顶,不能弹时将数压入栈中,若此时是第i个数,则bi=栈中元素个数

给定一些bi的值,还原这个排列,或判断无解

题解:

我的想法是倒着还原,具体看代码吧...我只想得动,讲不动。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int a[1000010],b[1000010],sta[1000010];
 4 int main()
 5 {
 6     int n,k;
 7     scanf("%d%d",&n,&k);
 8     for (int i=1;i<=k;i++)
 9     {
10         int p,x;
11         scanf("%d%d",&p,&x);
12         b[p]=x;
13     }
14     int last=n+1,top=0,tmp=1,fl=1;
15     for (int i=n;i>=1;i--)
16     {
17         if (b[i])
18         {
19             if (last==n+1)
20             {
21                 while (top<b[i])
22                 {
23                     top++;
24                     sta[top]=top;
25                 }
26                 tmp=top+1;
27                 a[i]=top;
28                             
29             }else 
30             {
31                 if (b[i]>=b[last])
32                 {
33                     top--;
34                     while (top<b[i])
35                     {
36                         top++;
37                         sta[top]=tmp;
38                         tmp++;    
39                     }
40                     a[i]=sta[top];
41                 }else 
42                 {
43                     //last-i
44                     //b[last]-b[i]
45                     if (last-i<b[last]-b[i]) 
46                     {
47                         fl=0;
48                         break;
49                     }
50                     int gg=last-1;
51                     top--;
52                     while (top>b[i]) 
53                     {
54                         a[gg]=sta[top];
55                         top--;    
56                         gg--;
57                     }
58                     a[i]=sta[top];
59                 }
60             }
61             last=i;    
62         }
63     }
64     if (last<b[last]) fl=0;
65     if (!fl)
66     {
67         printf("-1\n");
68         return 0;    
69     }
70     int gg=last-1;
71     top--;
72     while (top)
73     {
74         a[gg]=sta[top];
75         top--;    
76         gg--;
77     }
78     for (int i=1;i<=n;i++) if (!a[i]) a[i]=tmp++;
79     for (int i=1;i<n;i++) printf("%d ",a[i]); 
80     printf("%d\n",a[n]);
81 }

 

补题:

J

可重数集S,求所有大小为k的子集中的数的gcd的乘积

对一个10^14级别的数取模

吐槽:

降智了属于是,一路改进方法,最后临门一脚不会hhh

心态真的爆炸

题解:

考虑每个质数对答案的贡献,设f[i][j]表示质数i^j出现的次数,惊奇的发现,用类似筛法的东西可以完全统计所有的j对应的次数

只不过次数需要对phi(mo)取模

  1 #include<bits/stdc++.h>
  2 #pragma GCC optimize ("-Ofast")
  3 #pragma GCC optimize("unroll-loops")
  4 using namespace std;
  5 const int N=4e4+10;
  6 int pp[10000010];
  7 int sk,zs[5000000];
  8 int a[50000],b[80010];
  9 long long c[50000][32];
 10 long long cc[80020],wc[80020];
 11 struct aa
 12 {
 13     int x,z;
 14     long long w;
 15 }q[50000000];
 16 long long rll()
 17 {
 18     long long x=0;
 19     char ch=getchar();
 20     while (ch<'0'||ch>'9') ch=getchar();
 21     while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
 22     return x;
 23 }
 24 int read()
 25 {
 26     int x=0;
 27     char ch=getchar();
 28     while (ch<'0'||ch>'9') ch=getchar();
 29     while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
 30     return x;
 31 }
 32 int gcd(int x,int y)
 33 {
 34     if (x%y==0) return y;
 35     return gcd(y,x%y);
 36 }
 37 long long add(long long x,long long y,long long mo)
 38 {
 39     return (x+y)%mo;
 40 }
 41 long long mul(__int128_t x,__int128_t y,long long mo)
 42 {
 43     /*x=x%mo;
 44     long long ret=0;
 45     while (y)
 46     {
 47         if (y&1) ret=add(ret,x,mo);
 48         x=add(x,x,mo);
 49         y=y>>1;
 50     }
 51     return ret;
 52     return x*y%mo;*/
 53     __int128_t ret=x*y%mo;
 54     long long rr=ret;
 55     return rr;
 56 }
 57 long long ksm(long long x,long long y,long long mo)
 58 {
 59     long long ret=1;
 60     while (y)
 61     {
 62         if (y&1) ret=mul(ret,x,mo);
 63         x=mul(x,x,mo);
 64         y=y>>1;
 65     }
 66     return ret;
 67 }
 68 long long C(int x,int y)
 69 {
 70     if (x>=y) return c[x][y];
 71     return 0;
 72 }
 73 void wwo()
 74 {
 75     int n=read(),kkk=read();
 76     long long mo=rll();
 77     c[0][0]=1;
 78     c[1][0]=1;
 79     c[1][1]=1;
 80     long long m=mo,phmo=1;
 81     for (int i=1;i<=sk;i++)
 82     {
 83         if (m%zs[i]==0)
 84         {
 85             int cc=0;
 86             while (m%zs[i]==0)
 87             {
 88                 m=m/zs[i];
 89                 cc++;
 90             }
 91             for (int j=1;j<cc;j++) phmo=phmo*zs[i];
 92             phmo=phmo*(zs[i]-1);
 93         }
 94     }
 95     if (m!=1) phmo=phmo*(m-1);
 96     for (int i=2;i<=n;i++)
 97     {
 98         c[i][0]=1;
 99         for (int j=1;j<=kkk&&j<=i;j++)
100         {
101             c[i][j]=add(c[i-1][j-1],c[i-1][j],phmo);
102         }
103     }
104     for (int i=2;i<=80000;i++) b[i]=0;
105     for (int i=1;i<=n;i++) a[i]=read(),b[a[i]]++;
106     long long ans=1;
107     for (int i=2;i<=80000;i++)
108     {
109         cc[i]=0;
110         for (int j=i;j<=80000;j=j+i) cc[i]=cc[i]+b[j];
111     }
112     for (int i=1;i<=sk;i++)
113     {
114         if (zs[i]>80000) break;
115         long long tmp=0;
116         for (int j=zs[i];1;j=zs[i]*j)
117         {
118             tmp=tmp+C(cc[j],kkk);
119             if (80000/zs[i]<j) break;
120         }
121         ans=mul(ans,ksm(zs[i],tmp,mo),mo);
122     }
123     printf("%lld\n",ans);
124 }
125 int main()
126 {
127     sk=0;
128     for (int i=2;i<=10000000;i++)
129     {
130         if (!pp[i]) zs[++sk]=i;
131         for (int j=1;j<=sk&&i*zs[j]<=10000000;j++)
132         {
133             pp[i*zs[j]]=1;
134             if (i%zs[j]==0) break;
135         }
136     }
137     int t;
138     scanf("%d",&t);
139     while (t)
140     {
141         t--;
142         wwo();
143     }
144 }

 

posted @ 2021-07-19 21:30  praying_cqf  阅读(49)  评论(0编辑  收藏  举报