• 【模板】数据结构


    线段树:

    #include<iostream>
    #define MAXN 101000
    #define LL long long
    using namespace std;
    struct nond{
        LL l,r,dis,flag;    
    }tree[MAXN*4];
    int N,M,a,b,c,Z;
    void tree_up(LL now){
        tree[now].dis=tree[now*2].dis+tree[now*2+1].dis;
    }
    void tree_build(LL now,LL l,LL r){
        tree[now].l=l;
        tree[now].r=r;
        if(l==r){
            cin>>tree[now].dis;
            return;
        }
        LL mid=(tree[now].l+tree[now].r)/2;
        tree_build(now*2,l,mid);
        tree_build(now*2+1,mid+1,r);
        tree_up(now);
    }
    void tree_down(LL now){
        tree[now*2].flag+=tree[now].flag;
        tree[now*2+1].flag+=tree[now].flag;
        tree[now*2].dis+=tree[now].flag*(tree[now*2].r-tree[now*2].l+1);
        tree[now*2+1].dis+=tree[now].flag*(tree[now*2+1].r-tree[now*2+1].l+1);
        tree[now].flag=0;
        return ;
    }
    void tree_change_many(LL now,LL l,LL r,LL x){
        if(tree[now].l==l&&tree[now].r==r){
            tree[now].dis+=x*(tree[now].r-tree[now].l+1);
            tree[now].flag+=x;
            return ;
        }
        if(tree[now].flag)    tree_down(now);
        LL mid=(tree[now].l+tree[now].r)/2;
        if(r<=mid)    tree_change_many(now*2,l,r,x);
        else if(l>mid)    tree_change_many(now*2+1,l,r,x);
        else{
            tree_change_many(now*2,l,mid,x);
            tree_change_many(now*2+1,mid+1,r,x);
        }
        tree_up(now);
    }
    LL tree_query_many(LL now,LL l,LL r){
        if(tree[now].l==l&&tree[now].r==r){
            return tree[now].dis;
        }
        if(tree[now].flag)    tree_down(now);
        LL mid=(tree[now].l+tree[now].r)/2;
        if(r<=mid)    return tree_query_many(now*2,l,r);
        else if(l>mid)    return tree_query_many(now*2+1,l,r);
        else    return tree_query_many(now*2,l,mid)+tree_query_many(now*2+1,mid+1,r);
    }
    int main(){
        cin>>N>>M;
        tree_build(1,1,N);
        for(LL i=1;i<=M;i++){
            cin>>Z;
            if(Z==1){
                cin>>a>>b>>c;
                tree_change_many(1,a,b,c);
            }
            else if(Z==2){
                cin>>a>>b;
                cout<<tree_query_many(1,a,b)<<endl;
            }
        }
        return 0;
    }
    区间修改区间查询
    #include<cstdio>
    using namespace std;
    int n,p,a,b,m,x,ans;
    struct node
    {
        int l,r,w,f;
    }tree[400001];
    inline void build(int k,int ll,int rr)
    {
        tree[k].l=ll,tree[k].r=rr;
        if(tree[k].l==tree[k].r)
        {
            scanf("%d",&tree[k].w);
            return;
        }
        int m=(ll+rr)/2;
        build(k*2,ll,m);
        build(k*2+1,m+1,rr);
        tree[k].w=tree[k*2].w+tree[k*2+1].w;
    }
    inline void down(int k)
    {
        tree[k*2].f+=tree[k].f;
        tree[k*2+1].f+=tree[k].f;
        tree[k*2].w+=tree[k].f*(tree[k*2].r-tree[k*2].l+1);
        tree[k*2+1].w+=tree[k].f*(tree[k*2+1].r-tree[k*2+1].l+1);
        tree[k].f=0;
    }
    inline void add(int k)
    {
        if(tree[k].l>=a&&tree[k].r<=b)
        {
            tree[k].w+=(tree[k].r-tree[k].l+1)*x;
            tree[k].f+=x;
            return;
        }
        if(tree[k].f) down(k);
        int m=(tree[k].l+tree[k].r)/2;
        if(a<=m) add(k*2);
        if(b>m) add(k*2+1);
        tree[k].w=tree[k*2].w+tree[k*2+1].w;
    }
    inline void ask(int k)
    {
        if(tree[k].l==tree[k].r)
        {
            ans=tree[k].w;
            return;
        }
        if(tree[k].f) down(k);
        int m=(tree[k].l+tree[k].r)/2;
        if(x<=m) ask(k*2);
        else ask(k*2+1); 
    }
    int main()
    {
        scanf("%d",&n);
        build(1,1,n);
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d",&p);
            if(p==1)
            {
                scanf("%d%d%d",&a,&b,&x);
                add(1);
            }
            else
            {
                scanf("%d",&x);
                ask(1);
                printf("%d
    ",ans);
            }
        }
    }
    单点查询区间修改
    #include<cstdio>
    using namespace std;
    int n,m,p,x,y,ans;
    struct node
    {
        int l,r,w;
    }tree[400001];
    inline void build(int l,int r,int k)
    {
        tree[k].l=l;tree[k].r=r;
        if(l==r) 
        {
            scanf("%d",&tree[k].w);
            return ;
        }
        int m=(l+r)/2;
        build(l,m,k*2);
        build(m+1,r,k*2+1);
        tree[k].w=tree[k*2].w+tree[k*2+1].w;
    }
    inline void add(int k)
    {
        if(tree[k].l==tree[k].r)
        {
            tree[k].w+=y;
            return;
        }
        int m=(tree[k].l+tree[k].r)/2;
        if(x<=m) add(k*2);
        else add(k*2+1);
        tree[k].w=tree[k*2].w+tree[k*2+1].w; 
    }
    inline void sum(int k)
    {
        if(tree[k].l>=x&&tree[k].r<=y) 
        {
            ans+=tree[k].w;
            return;
        }
        int m=(tree[k].l+tree[k].r)/2;
        if(x<=m) sum(k*2);
        if(y>m) sum(k*2+1);
    }
    int main()
    {
        scanf("%d",&n);
        build(1,n,1);
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&p,&x,&y);
            ans=0;
            if(p==1) add(1);
            else 
            {
                sum(1);
                printf("%d
    ",ans);
            }
        }
    }
    单点查询取件修改
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define LL long long
    #define MAXN 100010
    using namespace std;
    LL l[MAXN<<2],r[MAXN<<2],dis[MAXN<<2],falg1[MAXN<<2],falg2[MAXN<<2];
    LL n,m,p;
    void up(LL now){
        dis[now]=(dis[now<<1]+dis[now<<1|1])%p;
    }
    void build(LL now,LL ll,LL rr){
        l[now]=ll;
        r[now]=rr;
        if(l[now]==r[now]){
            cin>>dis[now];
            return;
        }
        LL mid=(l[now]+r[now])>>1;
        build(now<<1,ll,mid);
        build(now<<1|1,mid+1,rr);
        up(now);
    }
    void down(LL now){
        if(falg1[now]!=1){
            falg2[now<<1]=falg2[now<<1]*falg1[now]%p;
            falg2[now<<1|1]=falg2[now<<1|1]*falg1[now]%p;
            dis[now<<1]=falg1[now]*dis[now<<1]%p;
            dis[now<<1|1]=falg1[now]*dis[now<<1|1]%p;
            falg1[now<<1]=falg1[now<<1]*falg1[now]%p;
            falg1[now<<1|1]=falg1[now<<1|1]*falg1[now]%p;
            falg1[now]=1;
        }
        if(falg2[now]){
            dis[now<<1]=(dis[now<<1]+falg2[now]*(r[now<<1]-l[now<<1]+1)%p)%p;
            dis[now<<1|1]=(dis[now<<1|1]+falg2[now]*(r[now<<1|1]-l[now<<1|1]+1)%p);
            falg2[now<<1]=(falg2[now<<1]+falg2[now])%p;
            falg2[now<<1|1]=(falg2[now<<1|1]+falg2[now])%p;
            falg2[now]=0;
        }
    }
    void changec(LL now,LL ll,LL rr,LL k){
        if(l[now]==ll&&r[now]==rr){
            dis[now]=dis[now]*k%p;
            falg1[now]=falg1[now]*k%p;
            falg2[now]=falg2[now]*k%p;
            return;
        }
        if(falg1[now]!=0||falg2[now])    down(now);
        LL mid=(l[now]+r[now])>>1;
        if(rr<=mid)    changec(now<<1,ll,rr,k);
        else if(ll>mid)    changec(now<<1|1,ll,rr,k);
        else{
            changec(now<<1,ll,mid,k);
            changec(now<<1|1,mid+1,rr,k);
        }    
        up(now);
    }
    void changej(LL now,LL ll,LL rr,LL k){
        if(l[now]==ll&&r[now]==rr){
            dis[now]=(dis[now]+k*(r[now]-l[now]+1)%p)%p;
            falg2[now]+=k;
            return;
        }
        if(falg1[now]!=1||falg2[now])    down(now);
        LL mid=(l[now]+r[now])>>1;
        if(rr<=mid)    changej(now<<1,ll,rr,k);
        else if(ll>mid)    changej(now<<1|1,ll,rr,k);
        else{
            changej(now<<1,ll,mid,k);
            changej(now<<1|1,mid+1,rr,k);
        }    
        up(now);
    }
    LL query(LL now,LL ll,LL rr){
        if(l[now]==ll&&r[now]==rr)
            return dis[now]%p;
        if(falg1[now]!=1||falg2[now])    down(now);
        LL mid=(l[now]+r[now])>>1;
        if(rr<=mid)    return query(now<<1,ll,rr);
        else if(ll>mid)    return query(now<<1|1,ll,rr);
        else    return query(now<<1|1,mid+1,rr)+query(now<<1,ll,mid);
    }
    int main(){
        cin>>n>>m>>p;
        build(1,1,n);
        memset(falg2,0,sizeof(falg2));
        for(LL i=1;i<=n*4;i++)
            falg1[i]=1;
        for(LL i=1;i<=m;i++){
            LL z,x,y,k;
            cin>>z>>x>>y;
            if(z==1){
                cin>>k;
                changec(1,x,y,k);
            } else if(z==2){
                cin>>k;
                changej(1,x,y,k);
            } else
                cout<<query(1,x,y)%p<<endl;
        }
    }
    带有加法和乘法的线段树

    trie树

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define MAXN 500010
    using namespace std;
    char s[50];
    int n,m,tot,len,root;
    int sum[MAXN],tree[MAXN][30];
    void insert(){
        root=0;
        len=strlen(s);
        for(int i=0;i<len;i++){
            int x=s[i]-'a';
            if(!tree[root][x])
                tree[root][x]=++tot;
            root=tree[root][x]; 
        }
        sum[root]=1;
    }
    void find(){
        root=0;
        len=strlen(s);
        for(int i=0;i<len;i++){
            int x=s[i]-'a';
            if(!tree[root][x]){
                cout<<"WRONG"<<endl;
                return ;
            }
            root=tree[root][x];
        }
        if(sum[root]==1){
            sum[root]++;
            cout<<"OK"<<endl;
            return ;
        }
        else{
            cout<<"REPEAT"<<endl;
            return ;
        }
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%s",s);
            insert();
        }
        scanf("%d",&m);
        for(int i=1;i<=m;i++){
            scanf("%s",s);
            find();    
        }
    }
    查询某个字符串是否出现过
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int trie[400001][26],len,root,tot,sum[400001];
    bool p;
    int n,m; 
    char s[11];
    void insert()
    {
        len=strlen(s);
        root=0;
        for(int i=0;i<len;i++)
        {
            int id=s[i]-'a';
            if(!trie[root][id]) trie[root][id]=++tot;
            sum[trie[root][id]]++;//前缀后移一个位置保存 
            root=trie[root][id];
        }
    }
    int search()
    {
        root=0;
        len=strlen(s);
        for(int i=0;i<len;i++)
        {
            int id=s[i]-'a';
            if(!trie[root][id]) return 0;
            root=trie[root][id];
        }//root经过此循环后变成前缀最后一个字母所在位置的后一个位置 
        return sum[root];//因为前缀后移了一个保存,所以此时的sum[root]就是要求的前缀出现的次数 
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            cin>>s;
            insert();
        }
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
            cin>s;
            printf("%d
    ",search());
        }
    }
    查询某个档次的出现次数

    ...

  • 相关阅读:
    Java学习笔记-关键字super
    Java学习笔记 -方法覆盖和多态
    刷题笔记-图论
    刷题笔记 -宽搜bfs和深搜dfs
    刷题笔记-双指针算法
    python之switch语句,优化多个if语句
    激光驱动上位机软件开发引言
    上位机开发之PyQt5知识点
    stm32 关于正负数的运算(待验证)
    c语言之关键字volatile
  • 原文地址:https://www.cnblogs.com/cangT-Tlan/p/7801026.html
Copyright © 2020-2023  润新知