1 条题解

  • 1
    @ 2021-04-14 16:41:28

    添加第三种符号是为了破坏连续性,期待能卡掉Medium的做法。(不知道有没有修改Medium做法然后过本题的方法)。
    标准做法是树状数组O(nlogn),但是个人比较喜欢暴力方法www,所以放宽时限让莫队算法O(n\(\sqrt n\))过了,擅长卡常的朋友可以用莫队去做洛谷P1972。
    (树状数组最后一个点1.2s.莫队最后一个点4.5s左右)

    莫队Code:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long int
    const int maxn=1e6+10,size=2000;
    int a[maxn],now[maxn],ans=1,out[maxn];
    struct node{
        int l,r;
        int index;
    }query[maxn];
    int cmp(node x,node y)
    {
        if((int)x.l/size == (int)y.l/size) return x.r<y.r;
        return x.l<y.l; 
    }
    void upd(int x){if(++now[a[x]]==1) ans++;}
    void del(int x){if(--now[a[x]]==0) ans--;}
    int main()
    {
        int n,m;scanf("%d%d",&n,&m);
        string s;cin>>s;
        for(int i=0;i<n;i++) 
        {
            if(s[i]=='+')a[i+1]=a[i]+1;
            if(s[i]=='-')a[i+1]=a[i]-1;
            if(s[i]=='*')a[i+1]=a[i]+3;
        }
        for(int i=1;i<=m;i++) scanf("%d%d",&query[i].l,&query[i].r),query[i].index=i;
        sort(query+1,query+1+m,cmp);
        int nowl=1,nowr=1;now[a[1]]++;
        for(int i=1;i<=m;i++)
        {
            while(query[i].r>nowr) nowr++,upd(nowr);
            while(query[i].r<nowr) del(nowr),nowr--;
            while(query[i].l<nowl) nowl--,upd(nowl);
            while(query[i].l>nowl) del(nowl),nowl++;
            out[query[i].index]=ans;
        }
        for(int i=1;i<=m;i++) printf("%d\n",out[i]);
        return 0;
    }
    
  • 1

F 奇怪的程序(Hard) /[模板]莫队算法

信息

ID
1236
难度
8
分类
(无)
标签
递交数
46
已通过
4
通过率
9%
被复制
5
上传者