[NOI 2016] 优秀的拆分
2018-01-22 10:34
323 查看
传送门
前19个点 N<=2000 N2的算法是可以通过的。
首先我们 N2处理出 f[i] 表示在以i结尾处之前满足 AA的子串个数
然后在 N2处理处 g[i] 表示在于i结尾处之前满足 AABB的子串个数
刚开始求区间hash值也用了N2的方法,前19个点用了2000ms+
后来想起来求区间hash值只需要O(N)处理+O(1)查询就可以了 前19个点用了 400ms+
刚开始写的时候一直错,因为我得到区间哈希值的时候int撑不下了,用了unsigned long long才OK
日后补坑~
不过95分已经非常良心了,233
暴力做法:
作为NOI 2016的第一题,本题暴力分非常良心,足足有95之多。前19个点 N<=2000 N2的算法是可以通过的。
首先我们 N2处理出 f[i] 表示在以i结尾处之前满足 AA的子串个数
然后在 N2处理处 g[i] 表示在于i结尾处之前满足 AABB的子串个数
刚开始求区间hash值也用了N2的方法,前19个点用了2000ms+
后来想起来求区间hash值只需要O(N)处理+O(1)查询就可以了 前19个点用了 400ms+
刚开始写的时候一直错,因为我得到区间哈希值的时候int撑不下了,用了unsigned long long才OK
#include <cstdio> #include <iostream> #include <cstring> #define ull unsigned long long using namespace std; const int mod1=100271,mod2=500179; char s[3000]; int f[3000],g[3000]; ull hash1[3000],hash2[3000]; ull base1[3000],base2[3000]; void make_hash(int n) { base1[0]=base2[0]=1; for(int i=1;i<=n;i++) { base1[i]=base1[i-1]*28%mod1; base2[i]=base2[i-1]*28%mod2; hash1[i]=(hash1[i-1]*28%mod1+(s[i]-'a'+1))%mod1; hash2[i]=(hash2[i-1]*28%mod2+(s[i]-'a'+1))%mod2; } } ull gethash1(int l,int r) { return (hash1[r]-(hash1[l-1]*base1[r-l+1])%mod1+mod1)%mod1; } ull gethash2(int l,int r) { return (hash2[r]-(hash2[l-1]*base2[r-l+1])%mod2+mod2)%mod2; } void work() { memset(hash1,0,sizeof(hash1)),memset(hash2,0,sizeof(hash2)); memset(f,0,sizeof(f)),memset(g,0,sizeof(g)); scanf("%s",(s+1)); int len=strlen(s+1); make_hash(len); for(int i=1;i<=len;i++) { int j; i%2==1?j=2:j=1; for(;j<i;j+=2) { int x=i-j+1; x=j+x/2-1; if(gethash1(j,x)==gethash1(x+1,i)&&gethash2(j,x)==gethash2(x+1,i)) f[i]++; } } int ans=0; for(int i=3;i<=len;i++) { int v=f[i-1],x; for(int j=i+1;j<=len;j+=2) { x=j-i+1;x=i+x/2-1; if(gethash1(i,x)==gethash1(x+1,j)&&gethash2(i,x)==gethash2(x+1,j)) g[j]+=v; } } for(int i=4;i<=len;i++) ans+=g[i]; printf("%d\n",ans); } int main() { int t; scanf("%d",&t); while(t--) work(); }
正解:我这只蒟蒻暂时还不会
好像得用后缀的数据结构,然而我还没学。日后补坑~
不过95分已经非常良心了,233
相关文章推荐
- 【uoj219】 NOI2016—优秀的拆分
- [后缀数组] BZOJ4650: [Noi2016] 优秀的拆分
- 【BZOJ 4650】【UOJ #219】【NOI 2016】优秀的拆分
- 字符串(后缀自动机):NOI 2016 优秀的拆分
- Noi2016 D1 T1 优秀的拆分 90做法
- [NOI 2016]优秀的拆分
- NOI 2016 优秀的拆分 后缀数组
- 【UOJ 219】【BZOJ 4650】【NOI 2016】优秀的拆分(后缀数组)
- 【BZOJ 4652】【NOI 2016】循环之美
- SQL Server 2016新增:string_split函数(拆分字符串)
- [NOI 2016]区间
- NOI2016 优秀的拆分 后缀数组
- [转]JAVA程序员一定知道的优秀第三方库(2016版)
- JAVA程序员一定知道的优秀第三方库(2016版)
- BZOJ 3668([Noi2014]起床困难综合症-2进制拆分)
- bzoj 4653: [Noi2016]区间
- [BZOJ]4653: [Noi2016]区间
- noi2016解题报告
- UOJ #219 [NOI2016 D1T1] 优秀的拆分 [95分]
- JZOJ4588. 【NOI2016模拟7.7】冷战 + 按秩合并讲解