P4135 作诗——分块

题目:https://www.luogu.org/problemnew/show/P4135

分块大法;

块之间记录答案,每一块记录次数前缀和;

注意每次把桶中需要用到位置赋值就好了;

为什么加了特判会 T 一个点?

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int const maxn=1e5+5;
int n,c,m,mod,a[maxn],ans,blk[maxn],base,t[maxn],cnt[320][maxn],bst[320],bed[320],f[320][320];
void pre(int x)
{
    int tmp=0,tem=x;
    memset(t,0,sizeof t);
    for(int i=bst[x];i<=n;i++)
    {
        t[a[i]]++;
        if(t[a[i]]%2==0)tmp++;
        else if(t[a[i]]>1)tmp--;
        if(i==bed[tem])f[x][tem]=tmp,tem++;
    }
}
int main()
{
    scanf("%d%d%d",&n,&c,&m);
    base=sqrt(n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]),blk[i]=(i-1)/base+1;
    for(int i=1;i<=blk[n];i++)bst[i]=(i-1)*base+1,bed[i]=min(n,i*base);
    for(int i=1;i<=blk[n];i++)pre(i);
    for(int i=1;i<=blk[n];i++)
    {
        for(int k=1;k<=c;k++)cnt[i][k]=cnt[i-1][k];
        for(int j=bst[i];j<=bed[i];j++)cnt[i][a[j]]++;
    }
    for(int i=1,l,r;i<=m;i++)
    {
        scanf("%d%d",&l,&r);
        l=(l+ans)%n+1; r=(r+ans)%n+1;
        if(l>r)swap(l,r);
//        if(l==r){printf("0\n"); ans=0; continue;}//ans=0!!!  //加特判变慢了???
        ans=0;
        if(blk[l]==blk[r])
        {
            for(int j=l;j<=r;j++)t[a[j]]=0;
            for(int j=l;j<=r;j++)
            {
                t[a[j]]++;
                if(t[a[j]]%2==0)ans++;
                else if(t[a[j]]>1)ans--;
            }
            printf("%d\n",ans);
        }
        else
        {
            if(blk[r]>blk[l]+1)ans=f[blk[l]+1][blk[r]-1];
            for(int j=l;j<=bed[blk[l]];j++)t[a[j]]=cnt[blk[r]-1][a[j]]-cnt[blk[l]][a[j]];
            for(int j=bst[blk[r]];j<=r;j++)t[a[j]]=cnt[blk[r]-1][a[j]]-cnt[blk[l]][a[j]];
            for(int j=l;j<=bed[blk[l]];j++)
            {
                t[a[j]]++;
                if(t[a[j]]%2==0)ans++;
                else if(t[a[j]]>1)ans--;
            }
            for(int j=bst[blk[r]];j<=r;j++)
            {
                t[a[j]]++;
                if(t[a[j]]%2==0)ans++;
                else if(t[a[j]]>1)ans--;
            }
            printf("%d\n",ans);
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Zinn/p/9302300.html

时间: 2024-08-29 09:14:22

P4135 作诗——分块的相关文章

【分块】P4135 作诗

分块太暴力惹... 没做出来.看了题解qaq 分析: 两头$\sqrt{n}$暴力维护 预处理ans[i][j],sum[i][j] sum[i][j]是一个前缀和,前i块值为j的数量 ans[i][j]表示第i块到第j块的答案总和 询问的时候先做两头,最后把ans[][]加上去就好了! 主要难点在预处理和卡常 1 #pragma GCC optimize(3) 2 #pragma GCC optimize(2) 3 #pragma GCC optimize("Ofast") 4 #i

P4135 作诗

传送门 分块 设sum[ i ] [ j ] 存从左边到第 i 块时,数字 j 的出现次数 f [ i ] [ j ] 存从第 i 块,到第 j 块的一整段的答案 那么最后答案就是一段区间中几块整段的答案加上两边小段的贡献 考虑两边小段的影响,对于每一个出现的数 它可能会使答案增加(使原本大区间中出现奇数次的数变成出现偶数次) 也可能使答案减少(使原本大区间中出现偶数次的数变成出现奇数次) 有了 sum 数组我们可以很方便地求出大区间中每个数的出现次数 对小段的每个数直接计算一下它对答案的贡献

【BZOJ2821】作诗(Poetize) 分块

Description 神犇SJY虐完HEOI之后给傻×LYD出了一题:SHY是T国的公主,平时的一大爱好是作诗.由于时间紧迫,SHY作完诗之后还要虐OI,于是SHY找来一篇长度为N的文章,阅读M次,每次只阅读其中连续的一段[l,r],从这一段中选出一些汉字构成诗.因为SHY喜欢对偶,所以SHY规定最后选出的每个汉字都必须在[l,r]里出现了正偶数次.而且SHY认为选出的汉字的种类数(两个一样的汉字称为同一种)越多越好(为了拿到更多的素材!).于是SHY请LYD安排选法.LYD这种傻×当然不会了

BZOJ 2821: 作诗(Poetize)( 分块 )

分块,分成N^0.5块.O(N^1.5)预处理出sm[i][j]表示前i块中j的出现次数, ans[i][j]表示第i~j块的答案. 然后就可以O(N^0.5)回答询问了.总复杂度O((N+Q)N^0.5) ----------------------------------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<

刷题总结——分块算法(bzoj2821作诗)

题目: Description 神犇SJY虐完HEOI之后给傻×LYD出了一题:SHY是T国的公主,平时的一大爱好是作诗.由于时间紧迫,SHY作完诗 之后还要虐OI,于是SHY找来一篇长度为N的文章,阅读M次,每次只阅读其中连续的一段[l,r],从这一段中选出一 些汉字构成诗.因为SHY喜欢对偶,所以SHY规定最后选出的每个汉字都必须在[l,r]里出现了正偶数次.而且SHY认 为选出的汉字的种类数(两个一样的汉字称为同一种)越多越好(为了拿到更多的素材!).于是SHY请LYD安排选 法.LYD这

BZOJ2821作诗【分块】

Description 神犇SJY虐完HEOI之后给傻×LYD出了一题:SHY是T国的公主,平时的一大爱好是作诗.由于时间紧迫,SHY作完诗之后还要虐OI,于是SHY找来一篇长度为N的文章,阅读M次,每次只阅读其中连续的一段[l,r],从这一段中选出一些汉字构成诗.因为SHY喜欢对偶,所以SHY规定最后选出的每个汉字都必须在[l,r]里出现了正偶数次.而且SHY认为选出的汉字的种类数(两个一样的汉字称为同一种)越多越好(为了拿到更多的素材!).于是SHY请LYD安排选法.LYD这种傻×当然不会了

巴蜀4384 -- 【模拟试题】作诗(Poetize)

Description 神犇SJY虐完HEOI之后给傻×LYD出了一题:SHY是T国的公主,平时的一大爱好是作诗.由于时间紧迫,SHY作完诗之后还要虐OI,于是SHY找来一篇长度为N的文章,阅读M次,每次只阅读其中连续的一段[l,r],从这一段中选出一些汉字构成诗.因为SHY喜欢对偶,所以SHY规定最后选出的每个汉字都必须在[l,r]里出现了正偶数次.而且SHY认为选出的汉字的种类数(两个一样的汉字称为同一种)越多越好(为了拿到更多的素材!).于是SHY请LYD安排选法.LYD这种傻×当然不会了

[Luogu 4135] 作诗

Description 神犇SJY虐完HEOI之后给傻×LYD出了一题: SHY是T国的公主,平时的一大爱好是作诗. 由于时间紧迫,SHY作完诗之后还要虐OI,于是SHY找来一篇长度为N的文章,阅读M次,每次只阅读其中连续的一段[l,r],从这一段中选出一些汉字构成诗.因为SHY喜欢对偶,所以SHY规定最后选出的每个汉字都必须在[l,r]里出现了正偶数次.而且SHY认为选出的汉字的种类数(两个一样的汉字称为同一种)越多越好(为了拿到更多的素材!).于是SHY请LYD安排选法. LYD这种傻×当然

「luogu4135」作诗

「luogu4135」作诗 传送门 分块好题. 预处理出 \(f[i][j]\) 表示 \(i\) 号块到 \(j\) 号块的答案,\(num[i][k]\) 表示 \(k\) 在前 \(i\) 块的出现次数,暴力预处理,暴力查询,复杂度 \(O(n \sqrt n)\) 参考代码: #include <algorithm> #include <cstdio> #include <cmath> #define rg register #define file(x) fr