├── 1d1dDPOptimization.cpp ├── AhoCorasick.cpp ├── BridgeTree.cpp ├── CentroidDecomposition.cpp ├── Dijkstra.cpp ├── DisjointSetUnion.cpp ├── DivideConquerDPOptimization.cpp ├── HeavyLightDecomposition.cpp ├── ImplicitTreap.cpp ├── LCA.cpp ├── LazyPropagation.cpp ├── PalindromicTree.cpp ├── PersistentSegmentTree.cpp ├── README.md ├── StringHashing.cpp ├── StronglyConnectedComponents.cpp ├── SuffixArray.cpp └── SuffixAutomaton.cpp /1d1dDPOptimization.cpp: -------------------------------------------------------------------------------- 1 | // Code for problem ACQUIRE on spoj, example usage of 1D-1D DP Optimization 2 | #include 3 | using namespace std; 4 | 5 | #define sd(mark) scanf("%d",&mark) 6 | #define ss(mark) scanf("%s",&mark) 7 | #define sl(mark) scanf("%lld",&mark) 8 | #define debug(mark) printf("check%d\n",mark) 9 | #define clr(mark) memset(mark,0,sizeof(mark)) 10 | #define F first 11 | #define S second 12 | #define MP make_pair 13 | #define PB push_back 14 | #define ll long long 15 | #define INF 100000000000000000ll 16 | vector< pair > s; 17 | 18 | vector > v; 19 | pair a[500010]; 20 | ll dp[500010]; 21 | inline ll C(int i,int j) 22 | { 23 | if(i>j) 24 | return 0; 25 | return v[i-1].F*v[j-1].S; 26 | } 27 | int main() 28 | { 29 | int n,i,j,t=1; 30 | while(t--) 31 | { 32 | s.clear(); 33 | v.clear(); 34 | sd(n); 35 | for(i=0;i=0;--i) 43 | { 44 | if(a[i].S>prev) 45 | { 46 | v.PB(a[i]); 47 | prev=a[i].S; 48 | } 49 | } 50 | 51 | 52 | // dp Calculation starts 53 | for(i=0;i<50010;++i) 54 | dp[i]=INF; 55 | dp[0]=0; 56 | s.push_back(MP(1,0)); 57 | 58 | n=v.size(); 59 | for(i=1;i<=n;++i) 60 | dp[i]=C(1,i); 61 | 62 | for(i=1;idp[i]+C(i+1,pos)) 69 | { 70 | if(s.back().Fdp[i]+C(i+1,mid)) 94 | hi=mid; 95 | else 96 | lo=mid+1; 97 | } 98 | mid=(lo+hi)/2; 99 | if(dp[s.back().S]+C(s.back().S+1,mid)>dp[i]+C(i+1,mid)) 100 | s.push_back(MP(mid,i)); 101 | break; 102 | } 103 | } 104 | int pos=lower_bound(s.begin(),s.end(),MP(i+1,1000000))-s.begin(); 105 | int best=s[pos-1].S; 106 | dp[i+1]=min(dp[i+1],dp[best]+C(best+1,i+1)); 107 | } 108 | printf("%lld\n",dp[n]); 109 | } 110 | } 111 | 112 | /* 113 | 20 114 | 3 98 115 | 23 66 116 | 44 59 117 | 46 30 118 | 73 28 119 | 87 15 120 | 87 9 121 | 90 6 122 | 99 1 123 | 100 1 124 | 100 1 125 | 100 1 126 | 100 1 127 | 100 1 128 | 100 1 129 | 100 1 130 | 100 1 131 | 100 1 132 | 100 1 133 | 100 1 134 | */ -------------------------------------------------------------------------------- /AhoCorasick.cpp: -------------------------------------------------------------------------------- 1 | // Code for problem 696 D on Codeforces, example usage of Aho Corasick 2 | #include 3 | using namespace std; 4 | 5 | #define sd(mark) scanf("%d",&mark) 6 | #define ss(mark) scanf("%s",&mark) 7 | #define sl(mark) scanf("%lld",&mark) 8 | #define debug(mark) printf("check%d\n",mark) 9 | #define clr(mark) memset(mark,0,sizeof(mark)) 10 | #define F first 11 | #define S second 12 | #define MP make_pair 13 | #define PB push_back 14 | #define ll long long 15 | #define N 210 16 | #define ALPHA 26 17 | #define INF 1000000000000000000ll 18 | 19 | // Aho Corasick Algorithm 20 | int node_cnt=0; 21 | int sufflink[N],parent[N],Char[N]; 22 | int Link[N][ALPHA],Next[N][ALPHA]; 23 | ll score[N];//summation of required value for all suffixes of string ending at current node 24 | vector End[N];//list of patterns ending here 25 | 26 | //extra Data structures 27 | ll a[N]; 28 | ll mat[N][N]; 29 | ll ans[N][N]; 30 | 31 | 32 | int suff(int n); 33 | int traverse(int cur,int c) //returns Next state for (cur,c) 34 | { 35 | if(Next[cur][c]!=-1) 36 | return Next[cur][c]; 37 | if(!cur) 38 | return Next[cur][c]=(Link[cur][c]!=-1 ? Link[cur][c] :0); 39 | return Next[cur][c]=(Link[cur][c]==-1 ? traverse(suff(cur),c) : Link[cur][c]); 40 | } 41 | int suff(int cur) //returns suffix link 42 | { 43 | if(sufflink[cur]!=-1) 44 | return sufflink[cur]; 45 | if(!parent[cur]) 46 | return sufflink[cur]=0; 47 | return sufflink[cur]=traverse(suff(parent[cur]),Char[cur]); 48 | } 49 | 50 | // calculates summation over all suffixes of string ending at current node 51 | inline ll calc(int cur) 52 | { 53 | if(score[cur]!=-1) 54 | return score[cur]; 55 | if(!cur) 56 | return score[cur]=0; 57 | ll ret=0; 58 | for(auto x:End[cur]) 59 | ret+=a[x]; 60 | return ret+calc(suff(cur)); 61 | } 62 | 63 | void go(int cur) //precomputes Next and sufflink for all states 64 | { 65 | if(cur==-1) 66 | return; 67 | suff(cur); 68 | calc(cur);//extra problem specific calculation 69 | for(int i=0;i>s; 169 | add(s,i); 170 | } 171 | //precompute 172 | go(0); 173 | 174 | //extra problem specific code 175 | for(i=0;i<=node_cnt;++i) 176 | { 177 | for(j=0;j<=node_cnt;++j) 178 | mat[j][i]=-INF; 179 | for(j=0;j 3 | using namespace std; 4 | 5 | #define sd(mark) scanf("%d",&mark) 6 | #define ss(mark) scanf("%s",&mark) 7 | #define sl(mark) scanf("%lld",&mark) 8 | #define debug(mark) printf("check%d\n",mark) 9 | #define clr(mark) memset(mark,0,sizeof(mark)) 10 | #define F first 11 | #define S second 12 | #define MP make_pair 13 | #define PB push_back 14 | #define ll long long 15 | #define INF 100000000 16 | #define N 300010 17 | vector > v[N]; 18 | pair,int> e[N]; 19 | int special[N]; 20 | int special_cnt[N]={0}; 21 | vector > tree[N]; 22 | int low[N]; 23 | int parent[N]; 24 | bool mark[N]; 25 | int disc[N]; 26 | int comp[N]; 27 | int t; 28 | int bicompcnt; 29 | int bicomp[N]; 30 | vector out[N]; 31 | void dfs1(int cur) 32 | { 33 | int i; 34 | mark[cur]=1; 35 | disc[cur]=t++; 36 | for(i=0;idisc[cur]) 44 | { 45 | e[v[cur][i].S].S=1; 46 | } 47 | } 48 | else if(v[cur][i].F!=parent[cur]) 49 | { 50 | low[cur]=min(low[cur],disc[v[cur][i].F]); 51 | } 52 | } 53 | } 54 | void find_bridges(int n) 55 | { 56 | int i; 57 | t=0; 58 | for(i=0;i0) 154 | printf("YES\n"); 155 | else 156 | printf("NO\n"); 157 | } -------------------------------------------------------------------------------- /CentroidDecomposition.cpp: -------------------------------------------------------------------------------- 1 | // Code for problem 342 E on codeforces, example usage of Centroid Decomposition 2 | #include 3 | using namespace std; 4 | 5 | #define sd(a) scanf("%d",&a) 6 | #define ss(a) scanf("%s",&a) 7 | #define sl(a) scanf("%lld",&a) 8 | #define clr(a) memset(a,0,sizeof(a)) 9 | #define debug(a) printf("check%d",a) 10 | #define rep(i) 11 | #define F first 12 | #define S second 13 | #define MP make_pair 14 | #define PB push_back 15 | #define ll long long 16 | #define N 100010 17 | #define LOGN 20 18 | #define INF 1e9 19 | vector v[N]; 20 | int p[N][LOGN],l[N]; 21 | 22 | void dfs1(int cur,int par) 23 | { 24 | int i; 25 | for(i=0;i=0;--j) 50 | if(l[p[x][j]]>=l[y]) 51 | x=p[x][j]; 52 | if(x==y) 53 | return x; 54 | for(j=LOGN-1;j>=0;--j) 55 | if(p[x][j]!=p[y][j]) 56 | { 57 | x=p[x][j]; 58 | y=p[y][j]; 59 | } 60 | return p[x][0]; 61 | } 62 | int dist(int x,int y) 63 | { 64 | return l[x]+l[y]-2*l[lca(x,y)]; 65 | } 66 | //------CENTROID-DECOMPOSITION------ 67 | int sz[N],c_par[N]; 68 | int cnt;//no. of nodes in current part 69 | bool mark[N]={0};//wether node has already been marked as centroid 70 | void dfs2(int cur,int par) 71 | { 72 | cnt++; 73 | sz[cur]=1; 74 | for(int i=0;icnt/2) 90 | return find_centroid(v[cur][i],cur); 91 | } 92 | return cur; 93 | } 94 | void decompose(int start,int par) 95 | { 96 | cnt=0; 97 | dfs2(start,0); 98 | int cur=find_centroid(start,0); 99 | mark[cur]=1; 100 | c_par[cur]=0; 101 | if(par) 102 | c_par[cur]=par; 103 | for(int i=0;i > v[N]; 6 | int d[N]; 7 | 8 | int dijkstra(int st,int en) 9 | { 10 | int i,cur; 11 | for(i=0;i > q; 17 | d[st]=0; 18 | q.push(MP(0,st)); 19 | while(!q.empty()) 20 | { 21 | pair p=q.top(); 22 | cur=p.S; 23 | if(cur==en) 24 | return d[cur]; 25 | q.pop(); 26 | if(mark[cur]) continue; 27 | mark[cur]=1; 28 | for(i=0;i(d[cur]+v[cur][i].S)) 31 | { 32 | d[v[cur][i].F]=(d[cur]+v[cur][i].S); 33 | q.push(MP(-d[v[cur][i].F],v[cur][i].F)); 34 | } 35 | } 36 | } 37 | return d[en]; 38 | } 39 | //------------------SNIPPET ENDS---------------------------------- -------------------------------------------------------------------------------- /DisjointSetUnion.cpp: -------------------------------------------------------------------------------- 1 | //SNIPPET FOR UNION-FIND------------------------- 2 | #define N 100010 3 | int parent[N]; //immediate parent of every node 4 | int Rank[N]; //Rank of each subset, where a subset is identified by its root. 5 | 6 | int find(int cur) 7 | { 8 | if(parent[cur]==cur) 9 | return cur; 10 | return parent[cur]=find(parent[cur]); 11 | } 12 | 13 | void Union(int x,int y) 14 | { 15 | int xroot=find(x); 16 | int yroot=find(y); 17 | if(xroot==yroot) 18 | return; 19 | if(Rank[xroot] 3 | using namespace std; 4 | 5 | #define sd(mark) scanf("%d",&mark) 6 | #define ss(mark) scanf("%s",&mark) 7 | #define sl(mark) scanf("%lld",&mark) 8 | #define clr(mark) memset(mark,0,sizeof(mark)) 9 | #define F first 10 | #define S second 11 | #define MP make_pair 12 | #define pb push_back 13 | #define ll long long 14 | #define INF 1000000000 15 | int u[4010][4010]; 16 | char s[8010]; 17 | int c[4010][4010]; 18 | int dp[4010][4010]; 19 | int best[4010][4010]; 20 | void divide_conquer(int i,int si,int sj,int l,int r) 21 | { 22 | if(si>sj) 23 | return; 24 | int mid=(si+sj)/2,minn=INF,best; 25 | for(int j=l;j 3 | using namespace std; 4 | 5 | #define sd(a) scanf("%d",&a) 6 | #define ss(a) scanf("%s",&a) 7 | #define sl(a) scanf("%lld",&a) 8 | #define clr(a) memset(a,0,sizeof(a)) 9 | #define debug(a) printf("check%d\n",a) 10 | #define rep(i) 11 | #define F first 12 | #define S second 13 | #define MP make_pair 14 | #define PB push_back 15 | #define ll long long 16 | #define N 100010 17 | 18 | vector v[N]; 19 | bool color[N]={0}; 20 | //----HEAVY-LIGHT---- 21 | vector t[N];//segment-tree fr each chain 22 | vector chain[N];//actual nodes contained in chain 23 | int ch_pos[N];//position of node in its chain 24 | int ch_id[N];//chain-id of node 25 | int head[N];//head of chain 26 | int par[N]; 27 | int sz[N]; 28 | int sp_child[N];//special child 29 | int cur_id=0;//current chain id 30 | void dfs(int cur,int p) 31 | { 32 | sz[cur]=1; 33 | par[cur]=p; 34 | for(int i=0;imaxx) 52 | { 53 | maxx=sz[v[cur][i]]; 54 | sp_child[cur]=v[cur][i]; 55 | } 56 | if(!maxx) 57 | { 58 | t[ch_id[cur]].resize(4*(int)chain[ch_id[cur]].size(),0); 59 | return; 60 | } 61 | dfs1(sp_child[cur],pos+1); 62 | for(int i=0;ien||sj>n>>q; 124 | for(i=0;i>x>>y; 128 | v[x].PB(y); 129 | v[y].PB(x); 130 | } 131 | heavy_light(n);//yay! 132 | while(q--) 133 | { 134 | int ch,x; 135 | cin>>ch>>x; 136 | if(!ch) 137 | { 138 | color[x]=(!color[x]); 139 | update(ch_id[x],1,0,(int)chain[ch_id[x]].size()-1,ch_pos[x],color[x]); 140 | } 141 | else 142 | cout< 3 | using namespace std; 4 | 5 | #define sd(a) scanf("%d",&a) 6 | #define ss(a) scanf("%s",&a) 7 | #define sl(a) scanf("%lld",&a) 8 | #define clr(a) memset(a,0,sizeof(a)) 9 | #define debug(a) printf("check%d\n",a) 10 | #define rep(i) 11 | #define F first 12 | #define S second 13 | #define MP make_pair 14 | #define PB push_back 15 | #define ll long long 16 | #define N 200010 17 | #define INF 1000000000 18 | 19 | struct node 20 | { 21 | int prior,size; 22 | ll val;//value stored in the array 23 | ll sum;//whatever info you want to maintain in segtree for each node 24 | ll lazy;//whatever lazy update you want to do 25 | int l,r; 26 | }t[N]; 27 | int node_cnt; 28 | int sz(int n) 29 | { 30 | if(n==-1) 31 | return 0; 32 | return t[n].size; 33 | } 34 | void upd_sz(int n) 35 | { 36 | if(n==-1) return; 37 | t[n].size=sz(t[n].l)+1+sz(t[n].r); 38 | } 39 | void push(int n) 40 | { 41 | if(n==-1) return; 42 | if(!t[n].lazy) return; 43 | 44 | t[n].val+=t[n].lazy;//operation of lazy 45 | t[n].sum+=t[n].lazy*t[n].size; 46 | 47 | if(t[n].l >= 0) 48 | t[t[n].l].lazy+=t[n].lazy;//propagate lazy 49 | if(t[n].r >= 0) 50 | t[t[n].r].lazy+=t[n].lazy;//propagate lazy 51 | t[n].lazy=0; 52 | } 53 | inline ll getsum(int n) 54 | { 55 | return n==-1?0:t[n].sum; 56 | } 57 | void refresh(int n) 58 | {//operation of segtree 59 | if(n==-1) return; 60 | 61 | push(t[n].l);push(t[n].r);//imp:propagate lazy before combining t->l,t->r; 62 | t[n].sum = t[n].val + getsum(t[n].l) + getsum(t[n].r); 63 | } 64 | pair split(int n,int pos,int add=0) 65 | { 66 | pair ret=MP(-1,-1); 67 | if(n==-1) 68 | return ret; 69 | push(n); 70 | int curr_pos = add + sz(t[n].l); 71 | if(curr_pos<=pos)//element at pos goes to left subtree(l) 72 | { 73 | pair p=split(t[n].r,pos,curr_pos+1); 74 | t[n].r = p.F; 75 | ret.S = p.S; 76 | ret.F = n; 77 | } 78 | else 79 | { 80 | pair p=split(t[n].l,pos,add); 81 | ret.F = p.F; 82 | t[n].l = p.S; 83 | ret.S = n; 84 | } 85 | upd_sz(ret.F);refresh(ret.F); 86 | upd_sz(ret.S);refresh(ret.S); 87 | return ret; 88 | } 89 | int merge(int l,int r) 90 | { 91 | int ret; 92 | push(l);push(r); 93 | if(l==-1) 94 | ret = r; 95 | else if(r==-1) 96 | ret = l; 97 | else if(t[l].prior > t[r].prior) 98 | { 99 | t[l].r = merge(t[l].r,r); 100 | ret=l; 101 | } 102 | else 103 | { 104 | t[r].l = merge(l,t[r].l); 105 | ret=r; 106 | } 107 | upd_sz(ret); 108 | refresh(ret); 109 | return ret; 110 | } 111 | int init(int val){ 112 | int ret = ++node_cnt; 113 | t[ret].prior=rand(); 114 | t[ret].size=1; 115 | t[ret].val=t[ret].sum=val; 116 | t[ret].lazy=0; 117 | t[ret].l=t[ret].r=-1; 118 | return ret; 119 | } 120 | 121 | // range query 122 | ll query(int &n,int l,int r){//[l,r] 123 | pair p = split(n,l-1); 124 | pair p1= split(p.S,r-l);//note: r-l!! 125 | refresh(p1.F); 126 | ll sum = (p1.F==-1?-INF:t[p1.F].sum); 127 | int n1 = merge(p.F,p1.F); 128 | n = merge(n1,p1.S); 129 | return sum; 130 | } 131 | 132 | //range update 133 | void update(int &n,int l, int r,ll val){ 134 | pair p = split(n,l-1); 135 | pair p1 = split(p.S,r-l); 136 | if(p1.F>=0) 137 | { 138 | t[p1.F].lazy += val; 139 | } 140 | int n1 = merge(p.F,p1.F); 141 | n = merge(n1,p1.S); 142 | } 143 | 144 | void Insert(int &n,int pos,ll val){ 145 | pair p = split(n,pos-1); 146 | int n1=merge(p.F,init(val)); 147 | n = merge(n1,p.S); 148 | } 149 | 150 | int a[N]; 151 | int main() 152 | { 153 | int t; 154 | sd(t); 155 | while(t--) 156 | { 157 | int n,m,i; 158 | sd(n);sd(m); 159 | node_cnt=-1; 160 | int root=-1; 161 | for(i=0;i 3 | using namespace std; 4 | 5 | #define sd(a) scanf("%d",&a) 6 | #define ss(a) scanf("%s",a) 7 | #define sl(a) scanf("%lld",&a) 8 | #define clr(a) memset(a,0,sizeof(a)) 9 | #define debug(a) printf("check%d\n",a) 10 | #define F first 11 | #define S second 12 | #define MP make_pair 13 | #define PB push_back 14 | #define ll long long 15 | #define N 1000010 16 | #define logn 23 17 | 18 | vector v[N]; 19 | int p[N][logn], minn[N][logn], l[N]; 20 | 21 | inline void dfs(int cur,int par) 22 | { 23 | l[cur]=l[par]+1; 24 | p[cur][0]=par; 25 | for(auto u:v[cur]) 26 | if(u!=par) 27 | dfs(u,cur); 28 | } 29 | inline int lca(int x,int y) 30 | { 31 | if(l[x]=0;--i) 34 | if(l[x]-(1<=l[y]) 35 | x=p[x][i]; 36 | if(x==y) 37 | return x; 38 | for(int i=logn-1;i>=0;--i) 39 | if(p[x][i]!=p[y][i]) 40 | { 41 | x=p[x][i]; 42 | y=p[y][i]; 43 | } 44 | return p[x][0]; 45 | } 46 | inline void pre_lca(int n) 47 | { 48 | for(int i=1;ien||sj=st&&sj<=en) 42 | { 43 | l[n]+=val; 44 | push(n,si,sj); 45 | return; 46 | } 47 | update(n*2,si,(si+sj)/2,st,en,val); 48 | update(n*2+1,(si+sj)/2+1,sj,st,en,val); 49 | refresh(n); 50 | } 51 | int query(int n,int si,int sj,int st,int en) 52 | { 53 | if(l[n]) 54 | push(n,si,sj); 55 | if(si>en||sj=st&&sj<=en) 58 | return maxx[n]; 59 | int v1=query(n*2,si,(si+sj)/2,st,en); 60 | int v2=query(n*2+1,(si+sj)/2+1,sj,st,en); 61 | refresh(n); 62 | return max(v1,v2); 63 | } -------------------------------------------------------------------------------- /PalindromicTree.cpp: -------------------------------------------------------------------------------- 1 | // Code for problem PALPROB on CodeChef, example usage of Palindromic Tree 2 | #include 3 | using namespace std; 4 | 5 | #define sd(a) scanf("%d",&a) 6 | #define ss(a) scanf("%s",a) 7 | #define sl(a) scanf("%lld",&a) 8 | #define clr(a) memset(a,0,sizeof(a)) 9 | #define debug(a) printf("check%d\n",a) 10 | #define F first 11 | #define S second 12 | #define MP make_pair 13 | #define PB push_back 14 | #define ll long long 15 | 16 | struct node 17 | { 18 | int en,l;//ending pos in s[] of first occurence of palindrome 19 | vector rev;//list of reverse suffix links 20 | int cnt;//number of times this palindrome has occured 21 | int suff;//suff. link 22 | int f[30];//list of outlinks 23 | node(int e,int len,int sl) 24 | { 25 | cnt=1; 26 | en=e; 27 | l=len; 28 | suff=sl; 29 | rev.clear(); 30 | for(int i=0;i<26;++i) 31 | f[i]=0; 32 | } 33 | node() 34 | { 35 | cnt=1; 36 | en=0; 37 | l=0; 38 | suff=0; 39 | rev.clear(); 40 | for(int i=0;i<26;++i) 41 | f[i]=0; 42 | } 43 | }; 44 | vector tree; 45 | char s[100010]; 46 | int first[30]; 47 | int p[100010]; 48 | void buildtree() 49 | { 50 | tree.clear(); 51 | tree.PB(node(0,-1,0)); 52 | tree.PB(node(0,0,0)); 53 | tree[0].rev.PB(1); 54 | int cur,next=0;//id of largest palindrome ending at pos, and next value of cur 55 | int pos=-1;//pos of last character added into pal. tree 56 | int l=strlen(s); 57 | for(pos=-1;pos=0&&s[pos+1]==s[pos-tree[cur].l])) 61 | { 62 | cur=tree[cur].suff; 63 | } 64 | if(tree[cur].f[s[pos+1]-'a']==0) 65 | { 66 | next=tree.size(); 67 | tree.PB(node(pos+1,tree[cur].l+2,-1)); 68 | tree[cur].f[s[pos+1]-'a']=next; 69 | tree[next].en=pos+1; 70 | cur=tree[cur].suff; 71 | while(!(pos-tree[cur].l>=0&&s[pos+1]==s[pos-tree[cur].l])) 72 | { 73 | cur=tree[cur].suff; 74 | } 75 | cur=tree[cur].f[s[pos+1]-'a']; 76 | if(cur==next) 77 | { 78 | tree[next].suff=1; 79 | tree[1].rev.PB(next); 80 | } 81 | else 82 | { 83 | tree[next].suff=cur; 84 | tree[cur].rev.PB(next); 85 | } 86 | } 87 | else 88 | { 89 | next=tree[cur].f[s[pos+1]-'a']; 90 | tree[next].cnt++; 91 | } 92 | } 93 | } 94 | int go(int cur)//calculates count 95 | { 96 | int i; 97 | for(i=0;i1) 113 | { 114 | p[tree[cur].l]=1+p[(tree[cur].l)/2]; 115 | ans=ans+(1+p[(tree[cur].l)/2])*tree[cur].cnt; 116 | } 117 | for(i=0;i 3 | using namespace std; 4 | 5 | #define sd(a) scanf("%d",&a) 6 | #define ss(a) scanf("%s",&a) 7 | #define sl(a) scanf("%lld",&a) 8 | #define clr(a) memset(a,0,sizeof(a)) 9 | #define debug(a) printf("check%d\n",a) 10 | #define F first 11 | #define S second 12 | #define MP make_pair 13 | #define PB push_back 14 | #define ll long long 15 | #define N 300010 16 | #define LIM 1000010 17 | 18 | struct node 19 | { 20 | int lc,rc,s; 21 | }t[N*100]; 22 | 23 | int root[LIM+10], node_cnt; 24 | int build_tree(int si,int sj) 25 | { 26 | int id=node_cnt++; 27 | if(si==sj) 28 | { 29 | t[id].s=0; 30 | return id; 31 | } 32 | t[id].lc=build_tree(si,(si+sj)/2); 33 | t[id].rc=build_tree((si+sj)/2+1,sj); 34 | t[id].s=t[t[id].lc].s+t[t[id].rc].s; 35 | return id; 36 | } 37 | 38 | 39 | int update(int id,int si,int sj,int pos) 40 | { 41 | int new_id=node_cnt++; 42 | t[new_id].s=t[id].s+1; 43 | t[new_id].lc=t[id].lc; 44 | t[new_id].rc=t[id].rc; 45 | if(si==sj) 46 | return new_id; 47 | if(pos<=(si+sj)/2) 48 | t[new_id].lc=update(t[id].lc,si,(si+sj)/2,pos); 49 | else 50 | t[new_id].rc=update(t[id].rc,(si+sj)/2+1,sj,pos); 51 | return new_id; 52 | } 53 | 54 | int query(int id,int si,int sj,int st,int en) 55 | { 56 | if(si>en||sj=st&&sj<=en) 59 | return t[id].s; 60 | return query(t[id].lc,si,(si+sj)/2,st,en)+query(t[id].rc,(si+sj)/2+1,sj,st,en); 61 | } 62 | 63 | int l[N],r[N]; 64 | int mark[LIM]; 65 | vector pts; 66 | vector v[N]; 67 | vector Query[N]; 68 | int cnt[N],comp[LIM]; 69 | 70 | int main() 71 | { 72 | int n,m,i,j; 73 | clr(mark); 74 | sd(n);sd(m); 75 | for(i=0;i 2 | using namespace std; 3 | 4 | #define sd(mark) scanf("%d",&mark) 5 | #define ss(mark) scanf("%s",&mark) 6 | #define sl(mark) scanf("%lld",&mark) 7 | #define debug(mark) printf("check%d\n",mark) 8 | #define clr(mark) memset(mark,0,sizeof(mark)) 9 | #define F first 10 | #define S second 11 | #define MP make_pair 12 | #define PB push_back 13 | #define ll long long 14 | #define LIM 1000010 15 | 16 | ll mod[2]={1000000007,1000000009}; 17 | 18 | ll front[2][LIM]; 19 | ll back[2][LIM]; 20 | 21 | ll p[2][LIM]; 22 | ll pInv[2][LIM]; 23 | 24 | char s[LIM]; 25 | 26 | ll pow1(ll a,ll b,ll mod){ 27 | if(b==0) return 1; 28 | ll ret=pow1(a,b/2,mod); 29 | ret=(ret*ret)%mod; 30 | if(b&1) ret=(a*ret)%mod; 31 | return ret; 32 | } 33 | 34 | void init() 35 | { 36 | p[0][0]=p[1][0]=1; 37 | pInv[0][0]=pInv[1][0]=1; 38 | for(int i=0;i<2;++i) 39 | { 40 | for(int j=1;j=0;--k) 59 | { 60 | back[j][k]=back[j][k+1]; 61 | back[j][k]=(back[j][k]+(s[k]-'a'+1)*p[j][l-1-k]%mod[j])%mod[j]; 62 | } 63 | } 64 | } 65 | 66 | inline ll HF(int l,int r,int f) 67 | { 68 | ll val=front[f][r]; 69 | if(l) 70 | val=(val-front[f][l-1]+mod[f])%mod[f]; 71 | val=(val*pInv[f][l])%mod[f]; 72 | return val; 73 | } 74 | 75 | inline ll HB(int l,int r,int f,int len) 76 | { 77 | ll val=back[f][l]; 78 | if(r calc_f(int l,int r) 85 | { 86 | return MP(HF(l,r,0),HF(l,r,1)); 87 | } 88 | inline pair calc_b(int l,int r,int len) 89 | { 90 | return MP(HB(l,r,0,len),HB(l,r,1,len)); 91 | } 92 | int main() 93 | { 94 | init(); 95 | ss(s); 96 | int l=strlen(s); 97 | init_hash(l); 98 | } 99 | -------------------------------------------------------------------------------- /StronglyConnectedComponents.cpp: -------------------------------------------------------------------------------- 1 | /*-----------code for scc-----------*/ 2 | #define N 100010 3 | stack order; 4 | bool mark[N]; 5 | vector v1[N];//forward graph 6 | vector v2[N];//reverse graph 7 | vector nodeList[N];// List of nodes in each scc 8 | int scc[N],sccCount;// id of scc each node belongs to 9 | void dfs(int cur) 10 | { 11 | int i; 12 | mark[cur]=1; 13 | for(i=0;i 3 | using namespace std; 4 | 5 | #define sd(a) scanf("%d",&a) 6 | #define ss(a) scanf("%s",&a) 7 | #define sl(a) scanf("%lld",&a) 8 | #define debug(a) printf("check%d\n",a) 9 | #define clr(a) memset(a,0,sizeof(a)) 10 | #define F first 11 | #define S second 12 | #define MP make_pair 13 | #define PB push_back 14 | #define ll long long 15 | #define N 500010 16 | int sortindex[20][N]; 17 | pair,int> sa[N]; 18 | int lcp[N]; 19 | int n; 20 | char s[N]; 21 | vector pos_string[2*N]; 22 | vector pos_sa[2*N]; 23 | int pre[N]; 24 | void buildSA() 25 | { 26 | 27 | int i,j; 28 | for(i=0;i=0;--i) 61 | { 62 | if(sortindex[i][x]==sortindex[i][y]) 63 | { 64 | ret+=(1<=n||y>=n) 68 | break; 69 | } 70 | } 71 | return ret; 72 | } 73 | void buildlcp() 74 | { 75 | int i; 76 | for(i=1;i 3 | using namespace std; 4 | 5 | #define sd(mark) scanf("%d",&mark) 6 | #define ss(mark) scanf("%s",&mark) 7 | #define sl(mark) scanf("%lld",&mark) 8 | #define debug(mark) printf("check%d\n",mark) 9 | #define clr(mark) memset(mark,0,sizeof(mark)) 10 | #define F first 11 | #define S second 12 | #define MP make_pair 13 | #define PB push_back 14 | #define ll long long 15 | #define INF 100000 16 | // suffix automaton 17 | #define N 100010 18 | #define M 28 19 | //alphabet size 20 | 21 | int getint(char c) 22 | { 23 | if(c>='a' && c<='z') 24 | return c-'a'; 25 | if(c=='$') 26 | return 26; 27 | return 27; 28 | } 29 | 30 | struct suffix_automata 31 | { 32 | vector Next[2*N]; 33 | int link[2*N],len[2*N],dp[2][2*N]; 34 | bool mark[2*N]; 35 | int node_cnt,last,ans; 36 | 37 | suffix_automata() 38 | { 39 | for(int i=0;i<2*N;++i) 40 | Next[i].resize(M,0); 41 | link[0]=-1; 42 | len[0]=0; 43 | last=0; 44 | node_cnt=1; 45 | ans=INF; 46 | clr(mark); 47 | } 48 | void add_letter(int c) 49 | { 50 | int cur=node_cnt++; 51 | int it=last; 52 | 53 | len[cur]=len[last]+1; 54 | last=cur; 55 | 56 | while(it!=-1) 57 | { 58 | if(Next[it][c]!=0) break; 59 | Next[it][c]=cur; 60 | it=link[it]; 61 | } 62 | if(it==-1) return (void)(link[cur]=0); 63 | if(len[it]+1==len[Next[it][c]]) return (void)(link[cur]=Next[it][c]); 64 | 65 | int clone=node_cnt++,q=Next[it][c]; 66 | link[clone]=link[q]; 67 | for(int i=0;i>s1>>s2; 109 | s = s1 + '$' +s2 + '#'; 110 | 111 | for(int i=0;i