模板和汇总
10.14 topsort
核心:模拟队列,切进入队列时候已经就是答案了,直接按照队列输出就可
注意while循环用输入量来作为终止
#include <stdio.h> #include <algorithm> #include <cstring> using namespace std; const int maxn=200020; int head[maxn],nex[maxn],ver[maxn],tot; int q[maxn]; int du[maxn]; int n; void topsort() { int hh=0,tt=-1; for(int i=1;i<=n;i++) if(du[i]==0) q[++tt]=i; while(hh<=tt) { int x=q[hh++]; for(int i=head[x];i;i=nex[i]) { int y=ver[i]; if(--du[y]==0) q[++tt]=y; } } } void add(int x,int y) { ver[++tot]=y; nex[tot]=head[x]; head[x]=tot; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { int a; while(scanf("%d",&a)!=0) { add(i,a); du[a]++; } } topsort(); for(int i=1;i<=n;i++) printf("%d ",q[i]); return 0; }
线段树:太重要了:
#include <stdio.h> #include <algorithm> #include <cstring> #include <cctype> #define mid ((l+r)>>1) #define lson (k<<1) #define rson (k<<1|1) using namespace std; const int maxn=200020; int s[maxn],tag[maxn]; int a[maxn]; int n,m; int read() { int x=0;char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) x=x*10+c-'0',c=getchar(); return x; } inline void build(int k,int l,int r) { if(l==r) { s[k]=a[l]; return; } build(lson,l,mid); build(rson,mid+1,r); s[k]=s[lson]+s[rson]; } inline void pushdown(int k,int l,int r) { if(!tag[k]) return; s[lson]+=(mid-l+1)*tag[k]; s[rson]=(r-mid)*tag[k]; tag[lson]+=tag[k]; tag[rson]+=tag[k]; tag[k]=0; } inline void change(int k,int l,int r,int x,int y,int v) { if(l>y||r<x) return; if(l>=x&&r<=y) { s[k]+=(r-l+1)*v; tag[k]+=v; return;//我们在push中提前计算左右儿子的影响,所以这里要return } pushdown(k,l,r); if(mid>=x) change(lson,l,mid,x,y,v); if(mid<y) change(rson,mid+1,r,x,y,v); s[k]=s[lson]+s[rson]; } inline int query(int k,int l,int r,int x,int y) { if(l>y||r<x) return 0; if(l>=x&&r<=y) return s[k]; pushdown(k,l,r); int res=0; if(mid>=x) res+=query(lson,l,mid,x,y); if(mid<y) res+=query(rson,mid+1,r,x,y); return res; } int main() { n=read();m=read(); for(int i=1;i<=n;i++) a[i]=read(); build(1,1,n); //for(int i=1;i<=n;i++) printf("%d ",s[i]); for(int i=1;i<=m;i++) { int mod; int x,y,z; mod=read(); if(mod==1) { x=read();y=read(); printf("%d\n",query(1,1,n,x,y)); } else { x=read();y=read();z=read(); change(1,1,n,x,y,z); } } return 0; }
高精度压位重载运算符模板:
/*²ÉÓÃÖØÔØÔËËã·û£¬Ñ¹Bλ Ö§³Ö¸ß¾«Êý¸³ÖµÓëÊä³ö¡¢¸ß¾«¼Ó(¼õ)¸ß¾«¡¢¸ß¾«³ËµÍ(¸ß)¾«¡¢¸ß¾«³ý(Ä£)µÍ¾«¡¢¸ß¾«µÄ±È½Ï ×¢Ò⣺Ôݲ»Ö§³Ö¸ºÊý£¡£¡£¡*/ #include<cstdio> #include<cstring> #include<stack> #include<iostream> #include<algorithm> using namespace std; typedef long long LL; const int N=128,B=4; const LL base=1e4;//ѹB룬baseΪ1eB struct HP{ private: int len;LL a[N]; inline void clear(){while(!a[len]&&len>1) --len;}//Çå³ýǰµ¼0 public: HP(){ //½á¹¹Ìå³õʼ»¯ memset(a,0ll,sizeof a);len=0; } //×¢ÒâÒòΪÊÇѹBλµÄ£¬ËùÒÔÊä³öÒªÌØÊâ´¦Àí void print(){//Êä³ö¸ß¾«¶ÈÊý printf("%lld",a[len]); for(int i=len-1;i>0;--i) for(int j=base/10;j>0;j/=10) printf("%lld",a[i]/j%10); puts(""); } /*ÒÔÏÂÊÇÖØÔØÔËËã·û*/ HP& operator =(LL x){//ÓÃLL³õʼ»¯¸ß¾«¶ÈÊý HPºó¼ÓÁË&²Å¿ÉÒÔʵÏÖÏña=b=cÕâÑùÁ¬Ðø¸³Öµ stack<char> st;string s; if(!x) return *this="0"; while(x){ st.push(x%10+'0'); x/=10; } while(!st.empty()) s+=st.top(),st.pop();//Æäʵ¾ÍÊǰÑintת»»ÎªstringÔÙµ÷ÓÃinit_s() return *this=s; } HP& operator =(const string &s){//ÓÃstring³õʼ»¯¸ß¾«¶ÈÊý memset(a,0ll,sizeof a);len=0;//ÕâÀ︳ֵΪ0²Å¿ÉÒÔ±£Ö¤Öظ´¸³ÖµÊ±²»»á³ö¹ø¡£¡£¡£ int l=s.length(); for(int i=0;i<=l;++i){ int j=(l-i+(B-1))/B;//ÒòΪѹBλËùÒÔÒªÌØÊâ´¦Àí a[j]=(a[j]<<1)+(a[j]<<3)+(s[i]^48); } len=(l+(B-1))/B; return *this; } HP operator +(const HP &x)const{//¸ß¾«¼Ó¸ß¾« HP res;res.len=max(len,x.len);LL k=0ll; for(int i=1;i<=res.len;++i){ res.a[i]=a[i]+x.a[i]+k; k=res.a[i]/base; res.a[i]%=base; } if(k>0) res.a[++res.len]=k; return res; } HP operator -(const HP &x)const{//¸ß¾«¼õ¸ß¾«(×¢ÒâÕâÀïĬÈϱ»¼õÊý´óÓÚ¼õÊý£¬·ñÔò»á³ö´í) HP res=*this;//Ï൱ÓÚÓÃres¿½±´±»¼õÊý for(int i=1;i<=len;++i){ res.a[i]-=x.a[i]; if(res.a[i]<0) --res.a[i+1],res.a[i]+=base; } res.clear(); return res; } HP operator *(const LL &x)const{//¸ß¾«³ËµÍ¾« HP res=*this; for(int i=1;i<=len;++i) res.a[i]*=x; for(int i=1;i<=len;++i) res.a[i+1]+=res.a[i]/base,res.a[i]%=base; int &end=res.len; while(res.a[end+1]>0){++end;res.a[end+1]+=res.a[end]/base,res.a[end]%=base;} return res; } HP operator *(const HP &x)const{//¸ß¾«³Ë¸ß¾« HP res;res.len=len+x.len; for(int i=1;i<=len;++i) for(int j=1;j<=x.len;++j){ res.a[i+j-1]+=a[i]*x.a[j]; res.a[i+j]+=res.a[i+j-1]/base; res.a[i+j-1]%=base; } res.clear(); return res; } HP operator /(const LL &x)const{//¸ß¾«³ýµÍ¾« HP res;res.len=len;LL k=0ll; for(int i=len;i>0;--i){ k=k*base+a[i]; res.a[i]=k/x; k%=x; } res.clear(); return res; } LL operator %(const LL &x)const{//¸ß¾«Ä£µÍ¾« LL k=0ll; for(int i=len;i>0;--i){ k=k*base+a[i]; k%=x; } return k;//Æäʵ¸ú¸ß¾«³ýµÍ¾«²î²»¶àµÄ£¬Ö»²»¹ý²»Óôæres,·µ»ØµÄÊÇk } bool operator <(const HP &x)const{//ÖØÔØÐ¡ÓںŠif(len==x.len){ int i; for(i=len;a[i]==x.a[i]&&i>1;--i); if(i>=1) return a[i]<x.a[i]; else return false; } else return len<x.len; } bool operator >(const HP &x)const{//ÖØÔØ´óÓںŠif(len==x.len){ int i; for(i=len;a[i]==x.a[i]&&i>1;--i); if(i>=1) return a[i]>x.a[i]; else return false; } else return len>x.len; } //Æäʵһ°ã´óÓÚºÍСÓÚºÅÖØÔØÒ»¸ö¾Í¹»ÓÃÁË }; HP max(const HP &a,const HP &b){ if(a>b) return a; return b; } HP min(const HP &a,const HP &b){ if(a<b) return a; return b; } HP a,b,ans; string sa,sb; int main() { cin>>sa>>sb; a=sa,b=sb; ans=a*b; ans.print(); return 0; }
树链剖分
#include <stdio.h> #include <algorithm> #include <cstring> #define lson (k<<1) #define rson (k<<1|1) #define mid ((l+r)>>1) using namespace std; const int maxn=100020; int s[maxn<<1],tag[maxn<<1]; int n,m,rt,p; int dep[maxn],sz[maxn],fa[maxn],son[maxn]; int rev[maxn],id[maxn],idx,top[maxn]; int a[maxn]; int head[maxn<<1],nex[maxn<<1],ver[maxn<<!1],tot; void add(int x,int y) { ver[++tot]=y; nex[tot]=head[x]; head[x]=tot; } void dfs(int x,int f) { dep[x]=dep[f]+1;fa[x]=f;sz[x]=1; for(int i=head[x];i;i=nex[i]) { int y=ver[i]; if(y==f) continue; dfs(y,x); sz[x]+=sz[y]; if(sz[y]>sz[son[x]])son[x]=y; } } void dfs2(int x,int t) { id[x]=++idx;rev[id[x]]=x;top[x]=t; if(!son[x]) return; dfs2(son[x],t); for(int i=head[x];i;i=nex[i]) { int y=ver[i]; if(y!=fa[x]&&y!=son[x]) dfs2(y,y); } } void build(int k,int l,int r) { if(l==r) { s[k]=a[rev[l]]; return ; } build(lson,l,mid); build(rson,mid+1,r); s[k]=(s[lson]+s[rson])%p; } void pushdown(int k,int l,int r)//距离的编写要注意 { if(!tag[k]) return ; tag[lson]=(tag[lson]+tag[k])%p; tag[rson]=(tag[rson]+tag[k])%p; s[lson]=(s[lson]+(mid-l+1)*tag[k])%p; s[rson]=(s[rson]+(r-mid)*tag[k])%p; tag[k]=0; return ; } void change(int k,int l,int r,int x,int y,int v) { if(l>y||r<x||l>r) return ; if(l>=x&&r<=y) { tag[k]=(tag[k]+v)%p; s[k]=(s[k]+(r-l+1)*v)%p; return; } pushdown(k,l,r); if(mid>=x) change(lson,l,mid,x,y,v); if(mid<y) change(rson,mid+1,r,x,y,v); s[k]=(s[lson]+s[rson])%p; return; } void update(int x,int y,int z) { while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); change(1,1,n,id[top[x]],id[x],z); x=fa[top[x]]; } if(id[x]>id[y]) swap(x,y); change(1,1,n,id[x],id[y],z); return ; } int query(int k,int l,int r,int x,int y) { if(l>y||r<x||l>r) return 0 ;//这里可以添加一下判断条件 if(l>=x&&r<=y) return s[k]; pushdown(k,l,r); int res=0; if(mid>=x) res+=query(lson,l,mid,x,y); if(mid<y) res+=query(rson,mid+1,r,x,y); res%=p; return res; } int ask(int x,int y) { int res=0; while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y);//注意id[x]的大小之间的关系 res+=query(1,1,n,id[top[x]],id[x]); res%=p; x=fa[top[x]]; } if(id[x]>id[y]) swap(x,y);//注意是idx res+=query(1,1,n,id[x],id[y]); res%=p; return res; } int main() { scanf("%d%d%d%d",&n,&m,&rt,&p); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<n;i++) { int x,y; scanf("%d%d",&x,&y); add(x,y); add(y,x); } dfs(rt,0);dfs2(rt,rt); build(1,1,n); for(int i=1;i<=m;i++) { int mod;scanf("%d",&mod); int x,y,z; if(mod==1) scanf("%d%d%d",&x,&y,&z),update(x,y,z); if(mod==2) scanf("%d%d",&x,&y),printf("%d\n",ask(x,y)); if(mod==3) scanf("%d%d",&x,&y),change(1,1,n,id[x],id[x]+sz[x]-1,y); if(mod==4) scanf("%d",&x),printf("%d\n",query(1,1,n,id[x],id[x]+sz[x]-1)); } return 0; }
树上的节点通过id[x]映射到线段树上面,以x为节点的子树的dfs序一定在id[x] id[x]+sz[x]-1的范围以内
修改节点和对应到线段树里面一定要注意就对啦
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1e5 + 5, maxm = maxn << 1; int a[maxn]; int head[maxm], nxt[maxm], v[maxm], cnt; int dad[maxn], depth[maxn], sz[maxn], son[maxn], root; int top[maxn], rak[maxn], id[maxn], dfx; int n, m, p; #define mid ((x + y) >> 1) #define lson (pst << 1) #define rson (pst << 1 | 1) #define len (y - x + 1) struct SegmentTree { int s[maxn << 1], tag[maxn << 1]; inline int Build(int x, int y, int pst) { if (x == y) s[pst] = a[rak[x]]; else s[pst] = Build(x, mid, lson) + Build(mid + 1, y, rson); return s[pst] % p; } inline void PushDown(int x, int y, int pst) { if (!tag[pst]) return; int k = tag[pst], lenl = mid - x + 1, lenr = y - mid; tag[lson] = (tag[lson] + k) % p, tag[rson] = (tag[rson] + k) % p; s[lson] = (s[lson] + k * lenl) % p, s[rson] = (s[rson] + k * lenr) % p; tag[pst] = 0; return; } inline void PushUp(int pst) { s[pst] = (s[lson] + s[rson]) % p; } inline void Update(int x, int y, int pst, int l, int r, int k) { if (x > y || y < l || x > r) return; if (l <= x && y <= r) { s[pst] = (s[pst] + k * len) % p; tag[pst] = (tag[pst] + k) % p; return; } PushDown(x, y, pst); Update(x, mid, lson, l, r, k), Update(mid + 1, y, rson, l, r, k); PushUp(pst); return; } inline int Query(int x, int y, int pst, int l, int r) { if (x > y || y < l || x > r) return 0; if (l <= x && y <= r) return s[pst]; PushDown(x, y, pst); return (Query(x, mid, lson, l, r) + Query(mid + 1, y, rson, l, r)) % p; } } ST; inline void Addline(int x, int y) { v[cnt] = y, nxt[cnt] = head[x], head[x] = cnt++; } inline void Dfs1(int x, int f, int d) { dad[x] = f, depth[x] = d, sz[x] = 1; for (int i = head[x]; ~i; i = nxt[i]) { if (v[i] == f) continue; Dfs1(v[i], x, d + 1); sz[x] += sz[v[i]]; if (sz[v[i]] > sz[son[x]]) son[x] = v[i]; } return; } inline void Dfs2(int x, int t) { top[x] = t, id[x] = ++dfx, rak[id[x]] = x; if (!son[x]) return; Dfs2(son[x], t); for (int i = head[x]; ~i; i = nxt[i]) if (v[i] != dad[x] && v[i] != son[x]) Dfs2(v[i], v[i]); return; } inline void Update(int x, int y, int k) { while (top[x] != top[y]) { if (depth[top[x]] < depth[top[y]]) swap(x, y); ST.Update(1, n, 1, id[top[x]], id[x], k); x = dad[top[x]]; } if (id[x] > id[y]) swap(x, y); ST.Update(1, n, 1, id[x], id[y], k); return; } inline int Query(int x, int y) { int ans = 0; while (top[x] != top[y]) { if (depth[top[x]] < depth[top[y]]) swap(x, y); ans = (ans + ST.Query(1, n, 1, id[top[x]], id[x])) % p; x = dad[top[x]]; } if (id[x] > id[y]) swap(x, y); ans += ST.Query(1, n, 1, id[x], id[y]); return ans % p; } signed main(void) { memset(head, -1, sizeof head); scanf("%d %d %d %d", &n, &m, &root, &p); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); for (int i = 1, x, y; i < n; i++) scanf("%d %d", &x, &y), Addline(x, y), Addline(y, x); Dfs1(root, 0, 1), Dfs2(root, root); ST.Build(1, n, 1); for (int i = 1, opt, x, y, z; i <= m; i++) { scanf("%d", &opt); if (opt == 1) scanf("%d %d %d" ,&x, &y, &z), Update(x, y, z); if (opt == 2) scanf("%d %d", &x, &y), printf("%d\n", Query(x, y)); if (opt == 3) scanf("%d %d", &x, &z), ST.Update(1, n, 1, id[x], id[x] + sz[x] - 1, z); if (opt == 4) scanf("%d", &x), printf("%d\n", ST.Query(1, n, 1, id[x], id[x] + sz[x] - 1)); } return 0; }
真模板
浙公网安备 33010602011771号