제출 #617122

#제출 시각아이디문제언어결과실행 시간메모리
617122senthetaPalinilap (COI16_palinilap)C++17
0 / 100
26 ms23988 KiB
#include<algorithm> #include<iostream> #include<cassert> #include<vector> #include<string> #include<array> #include<stack> #include<queue> #include<set> #include<map> using namespace std; #define V vector #define Int long long #define rep(i,a,b) for(Int i=(Int)(a); i<(Int)(b); i++) #define all(x) (x).begin(), (x).end() #define nl '\n' #define dbg(x) cout << "?" << #x << " : " << x << endl; #define int long long #define pii pair<int,int> const int N = 1e5+5; const int MOD = 1e9+7; int SEED, SINV[N]; int bpow(int a,int b){ int ret = 1; while(b){ if(b&1) ret = ret*a%MOD; a = a*a%MOD; b /= 2; } return ret; } int inv(int a){ return bpow(a, MOD-2); } int n; string s; // hash of ori string and reversed string int h[N], rh[N]; int qry(int l,int r){ int ret = h[r]; if(l) ret -= h[l-1]; (ret *= SINV[l] )%=MOD; if(ret<0) ret+=MOD; return ret; } int rqry(int l,int r){ int ret = rh[l]; if(r+1<n) ret -= rh[r+1]; (ret *= SINV[n-1-r] )%=MOD; if(ret<0) ret+=MOD; return ret; } // add arithmetic sequence to range // point query int loss[N]; #define mid ((tl+tr)/2) #define lc (v+1) #define rc (v+2*(mid-tl+1)) struct Segtree{ int lzl[2*N], lzr[2*N]; void upd(int l,int r,int addl,int addr,int v=0,int tl=0,int tr=n-1){ int a = addl, b = (r-l==0 ? 0:(addr-addl)/(r-l)); rep(i,l,r+1){ loss[i] += a + (i-l)*b; } return; if(r<tl || tr<l) return; if(l<=tl && tr<=r){ int a = addl, b = (r-l==0 ? 0:(addr-addl)/(r-l)); addl = a + (tl-l)*b; addr = a + (tr-l)*b; lzl[v] += addl; lzr[v] += addr; return; } upd(l,r,addl,addr, lc,tl,mid); upd(l,r,addl,addr, rc,mid+1,tr); } void build_loss(int v=0,int tl=0,int tr=n-1){ return; if(tl==tr){ // dbg(st[v]); loss[tl] = lzl[v]; return; } if(lzl[v] || lzr[v]){ upd(tl,tr,lzl[v],lzr[v], lc,tl,mid); upd(tl,tr,lzl[v],lzr[v], rc,mid+1,tr); lzl[v] = lzr[v] = 0; } build_loss(lc,tl,mid); build_loss(rc,mid+1,tr); } } segtree; // find longest [tl..l] == rev([r..tr]); int f(int l,int r){ if(l<0 || r<0 || n<=l || n<=r) return 0; int i=l, j=r; while(0<=i && j<n && s[i]==s[j]) i--,j++; return l-i; int len = 0; for(int J=1<<20; J; J/=2) if(len+J<=n && l-len-J+1>=0 && r+len+J-1<n && rqry(l-len-J+1,l)==qry(r,r+len+J-1)) len+=J; return len; } int gains[N][26]; int count_pali(){ int mul = 1; rep(i,0,n){ if(i) h[i] = h[i-1]; (h[i] += mul*s[i] )%=MOD; (mul *= SEED )%=MOD; } mul = 1; for(int i=n-1; i>=0; i--){ if(i+1<n) rh[i] = rh[i+1]; (rh[i] += mul*s[i] )%=MOD; (mul *= SEED )%=MOD; } int ret = 0; // even length palindrome rep(i,1,n){ // [l..i-1] == rev([i..r]) int len = f(i-1,i); int l = i-len, r = i+len-1; // dbg(i); dbg(len); dbg(l); dbg(r); // cout << nl; ret += len; } // odd length palindrome rep(i,0,n){ // [l..i] == rev([i..r]) int len = f(i,i); int l = i-len+1, r = i+len-1; // dbg(i); dbg(len); dbg(l); dbg(r); // cout << nl; ret += len; } return ret; } int ans = 0; signed main(){ srand(time(0)); SEED = rand()%MOD; // SEED = 3; SINV[0] = 1; SINV[1] = inv(SEED); rep(i,2,N){ (SINV[i] = SINV[i-1]*SINV[1] )%=MOD; } assert(SEED*SINV[1]%MOD==1); // n = 5; // segtree.upd(1,3, 1,5); // segtree.upd(2,4, 1,5); // segtree.build_loss(); // cout << "LOSS[]" << nl; // rep(i,1,5) cout << i << " " << loss[i] << nl; // return 0; cin >> s; n = s.size(); // rep(i,0,n) for(char c='a'; c<='z'; c++){ // swap(s[i], c); // ans = max(ans, count_pali()); // swap(s[i], c); // } // cout << ans << nl; return 0; int mul = 1; rep(i,0,n){ if(i) h[i] = h[i-1]; (h[i] += mul*s[i] )%=MOD; (mul *= SEED )%=MOD; } mul = 1; for(int i=n-1; i>=0; i--){ if(i+1<n) rh[i] = rh[i+1]; (rh[i] += mul*s[i] )%=MOD; (mul *= SEED )%=MOD; } // even length palindrome rep(i,1,n){ // [l..i-1] == rev([i..r]) int len = f(i-1,i); int l = i-len, r = i+len-1; // dbg(i); dbg(len); dbg(l); dbg(r); // cout << nl; ans += len; if(l<=i-1) segtree.upd(l,i-1, 1,len); if(i<=r) segtree.upd(i,r, len,1); // if char were changed if(0<=l-1 && r+1<n){ assert(s[l-1]!=s[r+1]); int tlen = f(l-2,r+2)+1; // dbg(tlen); gains[l-1][s[r+1]-'a'] += tlen; gains[r+1][s[l-1]-'a'] += tlen; } // cout << nl; } // cout << "##########" << nl; // odd length palindrome rep(i,0,n){ // [l..i] == rev([i..r]) int len = f(i,i); int l = i-len+1, r = i+len-1; // dbg(i); dbg(len); dbg(l); dbg(r); // cout << nl; ans += len; segtree.upd(i,i, len-1,len-1); if(l<=i-1) segtree.upd(l,i-1, 1,len-1); if(i+1<=r) segtree.upd(i+1,r, len-1,1); // if char were changed if(0<=l-1 && r+1<n){ assert(s[l-1]!=s[r+1]); int tlen = f(l-2,r+2)+1; // dbg(tlen); gains[l-1][s[r+1]-'a'] += tlen; gains[r+1][s[l-1]-'a'] += tlen; } } // dbg(ans); // get answer segtree.build_loss(); int maxdelta = 0; rep(i,0,n) rep(c,0,26){ int delta = gains[i][c] - loss[i]; maxdelta = max(maxdelta, delta); } ans += maxdelta; cout << ans << nl; }

컴파일 시 표준 에러 (stderr) 메시지

palinilap.cpp: In function 'long long int count_pali()':
palinilap.cpp:141:7: warning: unused variable 'l' [-Wunused-variable]
  141 |   int l = i-len, r = i+len-1;
      |       ^
palinilap.cpp:141:18: warning: unused variable 'r' [-Wunused-variable]
  141 |   int l = i-len, r = i+len-1;
      |                  ^
palinilap.cpp:153:7: warning: unused variable 'l' [-Wunused-variable]
  153 |   int l = i-len+1, r = i+len-1;
      |       ^
palinilap.cpp:153:20: warning: unused variable 'r' [-Wunused-variable]
  153 |   int l = i-len+1, r = i+len-1;
      |                    ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...