模板和汇总

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;
}
View Code

 线段树:太重要了:

#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; 
}
View Code

 树链剖分

#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;
}
View Code

真模板

 

posted @ 2020-10-14 12:51  ILH  阅读(91)  评论(0)    收藏  举报