zoukankan      html  css  js  c++  java
  • 17-09-20模拟赛

    T1:对于加法用前缀和sumi表示第i个数,对于修改,直接将sumi的值改为修改后的值。

    如果查询的区间[l,r]内有修改操作,那么就输出sumr,否则输出sumr-suml-1.

    注意需按题目要求解码,同时用long long存储部分数据。

    Code:

     1 #include<iostream>
     2 #include<cstdio>
     3 #define MN 10000005
     4 #define ll long long
     5 #define mod 998244353
     6 using namespace std;
     7 unsigned int seed,a[MN];
     8 int n,m,l[MN],r[MN],ans=0,sum[MN],pos[MN],pwr=1;
     9 bool type[MN];
    10 unsigned int GetNext(){
    11     seed^=(seed<<7);seed^=(seed>>8);seed^=(seed<<13);
    12     return seed;
    13 }
    14 int main()
    15 {
    16     scanf("%d%d%u",&n,&m,&seed);sum[0]=pos[0]=0;
    17     for (int i=1;i<=n;++i) type[i]=GetNext()%2,a[i]=GetNext();
    18     for (int i=1;i<=n;++i){
    19         if (!type[i]) sum[i]=(1ll*sum[i-1]+(1ll*a[i])%mod)%mod,pos[i]=pos[i-1];
    20         else pos[i]=i,sum[i]=(1ll*a[i])%mod;
    21     }for (int i=1;i<=m;++i){
    22         l[i]=GetNext()%n+1,r[i]=GetNext()%n+1;int tmp;
    23         if(l[i]>r[i]) tmp=l[i],l[i]=r[i],r[i]=tmp;
    24         ll res=0ll;pwr=(233ll*pwr)%mod;
    25         res=(l[i]<=pos[r[i]]?sum[r[i]]:sum[r[i]]-sum[l[i]-1]);
    26         if (res<0) res+=mod;ans=(1ll*ans+(1ll*pwr*res)%mod)%mod;
    27     }cout<<ans;return 0;
    28 }

    T2:可知若两个字符串的最小表示相同,那么它们循环同构。

    对每个字符串求其最小表示,将其最小表示插入trie树中。时间复杂度O(nm).

    亦可用字符串hash通过此题。

    Code:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define MN 1000005
     5 using namespace std;
     6 inline int in(){
     7     int x=0;bool f=0; char c;
     8     for (;(c=getchar())<'0'||c>'9';f=c=='-');
     9     for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0');
    10     return f?-x:x;
    11 }
    12 char s[MN<<1];
    13 int f[MN][26],v[MN],n,m,pos,u,cnt=0;
    14 long long ans=0ll;
    15 inline int expr(){
    16     int i=0,j=1;while (i<m&&j<m){
    17         int k=0;
    18         while (s[i+k]==s[j+k]&&k<m-1) ++k;
    19         if (s[i+k]<s[j+k]) j+=k+1;else i+=k+1;
    20         if (i==j) ++j;
    21     }return i<j?i:j;
    22 }
    23 int main()
    24 {
    25     n=in();m=in();for (int i=1;i<=n;++i){
    26         scanf("%s",s);for (int j=0;j<=m;++j) s[j+m]=s[j];
    27         pos=expr();u=1;
    28         for (int i=0;i<m;++i){
    29             if (!f[u][s[pos+i]-'a']) f[u][s[pos+i]-'a']=(++cnt);
    30             u=f[u][s[pos+i]-'a'];
    31         }ans+=1ll*v[u];++v[u];
    32     }printf("%lld",ans);return 0;
    33 }

    T3:树形dp.

    易知答案为叶子节点中的一个值。从大到小考虑每个数字,将大于或等于该数字k的数字认为是合法的。

    f[i]表示i的能量值v[i]合法时最少需要填充的数字个数。

    对于叶子节点i不能被交换时,v[i]合法,则f[i]=0,否则f[i]=inf.对于i可以被交换时,f[i]=1.

    对于非叶结点i,v[i]等于i的三个儿子中f值较小的两个儿子的f[i]值之和。判断f[1]是否超过m即可。

    易知k值越小时f值越小,合法的数字越多,具有单调性。考虑二分答案。时间复杂度O(n log n).

    Code:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define MN 1000005
     5 #define inf 1000000000
     6 using namespace std;
     7 inline int in(){
     8     int x=0;bool f=0; char c;
     9     for (;(c=getchar())<'0'||c>'9';f=c=='-');
    10     for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0');
    11     return f?-x:x;
    12 }
    13 int f[MN][3],val[MN],st[MN],n,m,x,cnt=0,ans;
    14 bool tr[MN];
    15 inline int dp(int u,int v){
    16     if (f[u][0]==-1) return tr[u]?1:(val[u]>=v?0:inf);
    17     else {
    18         int sum[3];memset(sum,0,sizeof(sum));
    19         for (int i=0;i<3;++i) sum[i]=dp(f[u][i],v);
    20         sort(sum,sum+3);return min(n+1,sum[0]+sum[1]);
    21     }
    22 }
    23 int main()
    24 {
    25     n=in();m=in();for (int i=1;i<=n;++i){
    26         f[i][0]=in();if (f[i][0]==-1) val[i]=in();
    27         else f[i][1]=in(),f[i][2]=in();
    28     }for (int i=1;i<=m;++i){
    29         x=in();tr[x]=1;st[++cnt]=val[x];
    30     }sort(st+1,st+cnt+1);int l=1,r=inf;
    31     while (l<=r){
    32         int mid=(l+r)>>1;
    33         if (dp(1,mid)<=cnt-(lower_bound(st+1,st+cnt+1,mid)-st)+1) 
    34         ans=mid,l=mid+1;else r=mid-1;
    35     }printf("%d",ans);return 0;
    36 }
  • 相关阅读:
    HDU4366 Successor 线段树+预处理
    POJ2823 Sliding Window 单调队列
    HDU寻找最大值 递推求连续区间
    UVA846 Steps 二分查找
    HDU3415 Max Sum of MaxKsubsequence 单调队列
    HDU时间挑战 树状数组
    UVA10168 Summation of Four Primes 哥德巴赫猜想
    UESTC我要长高 DP优化
    HDUChess 递推
    HDU4362 Dragon Ball DP+优化
  • 原文地址:https://www.cnblogs.com/codingutopia/p/test170920.html
Copyright © 2011-2022 走看看