ACM-ICPC 2018 焦作赛区网络预赛 做题记录

今天H题真的有毒,居然不放单组数据范围……SAM卡了半天空间打死过不去

J题卡牛顿迭代常数也是很那啥的

补题进度:6/12

A.

签到题,模拟

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int T;
 4 int main()
 5 {
 6     scanf("%d",&T);
 7     while(T--)
 8     {
 9         string s;
10         cin>>s;
11         for(int i=0;i<s.length();++i)
12         {
13             if('A'<=s[i]&&s[i]<='Z')s[i]=s[i]-'A'+'a';
14         }
15         if(s=="jessie")puts("Good guy!");
16         else puts("Dare you say that again?");
17     }
18     return 0;
19 }

G.

打表找规律,发现是2^(n-1),欧拉定理指数取模一下

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define maxn 1000005
 4 using namespace std;
 5 const ll mod=1000000007;
 6 int T;
 7 char s[maxn];
 8 ll fastpow(ll a,ll p)
 9 {
10     ll ans=1;
11     while(p)
12     {
13         if(p&1)ans=ans*a%mod;
14         a=a*a%mod;
15         p>>=1;
16     }
17     return ans;
18 }
19 int main()
20 {
21     scanf("%d",&T);
22     while(T--)
23     {
24         scanf("%s",s+1);
25         ll n=0,len=strlen(s+1);
26         for(int i=1;i<=len;++i)n=n*10+s[i]-'0',n%=(mod-1);
27         n=(n-1+(mod-1))%(mod-1);
28         ll ans=fastpow(2,n);
29         cout<<ans<<endl;
30     }
31     return 0;
32 }

H.

后缀自动机裸题,统计right集合大小在[A,B]之间的,每次maxlen[u]-minlen[u]+1就行

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define maxn 200005
 4 using namespace std;
 5 int ch[maxn][26];
 6 int fa[maxn],cnt,last,rt;
 7 ll sz[maxn],dis[maxn];
 8 void init()
 9 {
10     cnt=0;
11     rt=last=++cnt;
12     memset(fa,0,sizeof(fa));
13     memset(dis,0,sizeof(dis));
14     memset(sz,0,sizeof(sz));
15     memset(ch,0,sizeof(ch));
16 }
17 inline int newnode(int x){dis[++cnt]=x;return cnt;}
18 void add(int x)
19 {
20     int np=newnode(dis[last]+1),p=last;
21     for(;p&&(!ch[p][x]);p=fa[p])ch[p][x]=np;
22     if(!p)fa[np]=rt;
23     else
24     {
25         int q=ch[p][x];
26         if(dis[q]==dis[p]+1)fa[np]=q;
27         else
28         {
29             int nq=newnode(dis[p]+1);
30             memcpy(ch[nq],ch[q],sizeof(ch[q]));
31             fa[nq]=fa[q];
32             fa[q]=fa[np]=nq;
33             for(;ch[p][x]==q;p=fa[p])ch[p][x]=nq;
34         }
35     }
36     last=np;
37     sz[np]=1;
38 }
39 char s[maxn];
40 int A,B;
41 int c[maxn],t[maxn];
42 ll count()
43 {
44     memset(c,0,sizeof(c));
45     memset(t,0,sizeof(t));
46     ll ans=0;
47     for(int i=1;i<=cnt;i++)c[dis[i]]++;
48     for(int i=1;i<=cnt;i++)c[i]+=c[i-1];
49     for(int i=cnt;i;i--)t[c[dis[i]]--]=i;
50     for(int i=cnt;i;i--){int x=t[i];sz[fa[x]]+=sz[x];}
51     for(int i=2;i<=cnt;++i)if(A<=sz[i]&&sz[i]<=B)ans+=dis[i]-dis[fa[i]];
52     return ans;
53 }
54 int main()
55 {
56     while(~scanf("%s%d%d",s+1,&A,&B))
57     {
58         init();
59         for(int i=1;s[i];++i)add(s[i]-'A');
60         cout<<count()<<endl;
61     }
62     return 0;
63 }

I.

观察一下,三个都是奇数显然不行,否则显然可以

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int a,b,c; 
 4 int main()
 5 {
 6     while(~scanf("%d%d%d",&a,&b,&c))
 7     {
 8         if((a&1)&&(b&1)&&(c&1))puts("No");
 9         else puts("Yes");
10     }
11     return 0;
12 }

K.

多重背包计数,暴力dp为O(N*S*S)的

考虑把转移中的O(S)优化掉:

如果没有c[i]限制,那么每次记录 mod v[i]意义下分类的总和,每次加上总和即可

现在有了c[i]限制,考虑mod v[i]意义下是连续的一段转移过来的,所以用滑动窗口维护下就行了

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define maxn 22
 4 #define maxc 10005
 5 using namespace std;
 6 const ll mod=1000000007;
 7 int T,n,q;
 8 ll v[maxn],c[maxn];
 9 ll dp[maxn][maxc],tmp[maxn];
10 queue<ll> que[maxn];
11 int main()
12 {
13     scanf("%d",&T);
14     while(T--)
15     {
16         memset(dp,0,sizeof(dp));
17         scanf("%d%d",&n,&q);
18         for(int i=1;i<=n;++i)scanf("%lld%lld",&v[i],&c[i]);
19         dp[0][0]=1;
20         for(int i=1;i<=n;++i)
21         {
22             memset(tmp,0,sizeof(tmp));
23             for(int i=0;i<=20;++i)while(!que[i].empty())que[i].pop(); 
24             for(int j=0;j<=10000;++j)
25             {
26                 tmp[j%v[i]]+=dp[i-1][j];
27                 tmp[j%v[i]]%=mod;
28                 if(j>=((1<<c[i]))*v[i])tmp[j%v[i]]-=que[j%v[i]].front(),que[j%v[i]].pop(),tmp[j%v[i]]=(tmp[j%v[i]]%mod+mod)%mod;
29                 que[j%v[i]].push(dp[i-1][j]);
30                 dp[i][j]+=tmp[j%v[i]];dp[i][j]%=mod;
31             }
32         }
33         while(q--)
34         {
35             int s;
36             scanf("%d",&s);
37             printf("%d\n",(int)dp[n][s]);
38         }
39     }
40     return 0;
41 }

L.

dp;

f(i,j,k)表示现在是第i天,状态为j(0/1/2),上一天状态为k(0/1/2)

f(i,0,0)=f(i-1,0,1)+f(i-1,0,2);
f(i,0,1)=f(i-1,1,0)+f(i-1,1,1)+f(i-1,1,2);
f(i,0,2)=f(i-1,2,0)+f(i-1,2,2);
f(i,1,0)=f(i,0,1);
f(i,1,1)=f(i,0,0);
f(i,1,2)=f(i,0,2);
f(i,2,0)=f(i-1,0,0)+f(i-1,0,1);
f(i,2,1)=f(i,2,0);
f(i,2,2)=f(i-1,2,0)+f(i-1,2,1);

然后发现都是线性齐次递推,直接构造9*9的矩阵,上矩阵快速幂

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const ll mod=1000000007;
 5 int T;
 6 ll n;
 7 const int m=9;
 8 struct Matrix
 9 {
10     ll a[25][25];
11     void clear(){memset(a,0,sizeof(a));}
12     void init(){memset(a,0,sizeof(a));for(int i=1;i<=m;i++)a[i][i]=1;}
13 };
14 Matrix operator * (Matrix a,Matrix b)
15 {
16     Matrix c;c.clear();
17     for(int i=1;i<=m;i++)
18     for(int j=1;j<=m;j++)
19     for(int k=1;k<=m;k++)
20     c.a[i][j]+=a.a[i][k]*b.a[k][j]%mod,c.a[i][j]%=mod;
21     return c;
22 }
23 Matrix fastpow(Matrix a,ll p)
24 {
25     Matrix ans;ans.init();
26     for(;p;p>>=1,a=a*a)if(p&1)ans=ans*a;
27     return ans;
28 }
29 int main()
30 {
31     cin>>T;
32     while(T--)
33     {
34         cin>>n;
35         if(n==1)
36         {
37             puts("3");
38             continue;
39         }
40         Matrix A;A.clear();
41         A.a[1][2]=A.a[1][3]=A.a[2][4]=A.a[2][5]=A.a[2][6]=A.a[3][7]=A.a[3][9]=A.a[4][4]=A.a[4][5]=A.a[4][6]=1;
42         A.a[5][2]=A.a[5][3]=A.a[6][7]=A.a[6][9]=A.a[7][1]=A.a[7][2]=A.a[8][1]=A.a[8][2]=A.a[9][7]=A.a[9][8]=1;
43         Matrix res=fastpow(A,n-2);
44         Matrix tmp;tmp.clear();
45         for(int i=1;i<=9;++i)tmp.a[i][1]=1;
46         Matrix R=res*tmp;
47         ll ans=0;
48         for(int i=1;i<=9;++i)ans+=R.a[i][1];
49         ans%=mod;
50         cout<<ans<<endl;
51     }
52     return 0;
53 }

猜你喜欢

转载自www.cnblogs.com/uuzlove/p/9651700.html
今日推荐