zoukankan      html  css  js  c++  java
  • Luogu P5070 [Ynoi2015]即便看不到未来

    回坑做ynoi,然后发现自己的脑子就是一团浆糊

    首先仔细阅读题目,我们发现由于是对于询问的区间先排序后在讨论(刚开始看错了以为不可做题),所以显然可以离线一波

    把询问按右端点从小到大排,每次加入右边的位置然后询问左端点的答案

    考虑加入一个数之后的贡献,容易发现有四种:

    1. 这个数不和之前的任何数相邻,单独加上(1)的贡献
    2. 这个数在一边和之前的数相邻,要把原来的贡献减(1)然后加上现在(1)的贡献
    3. 这个数在两边都和其他数相邻,把两边的贡献都减了然后加上这一段长的
    4. 这个数以前出现过了,那么只处理从上次出现位置到当前位置的贡献变化

    然后我们容易把贡献的影响归为一类,即对于加入的(a_i),若((a_i-fr,a_i))((a_i,a_i+bk))均出现过

    那么删除((a_i-fr,a_i))((a_i,a_i+bk))的贡献然后加入((a_i-fr,a_i+bk))的贡献即可

    然后我们发现这个东西和答案都不大好维护的样子,那不是GG

    细细一看题目原来查询的区间长度都是(le 10)的,那么就意味着我们每次只需要暴力扫一遍((a_i-11,a_i))((a_i,a_i+11))即可进行更新

    同理我们也可以直接开(10)个树状数组来维护贡献,具体地直接记录后缀和即可

    注意更新贡献的时候要从后往前做才能防止重漏

    具体实现详见代码

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    #include<iostream>
    #define RI register int
    #define CI const int&
    #define Tp template <typename T>
    using namespace std;
    const int N=1e6+5;
    struct ques
    {
    	int l,r,id;
    	friend inline bool operator < (const ques& A,const ques& B)
    	{
    		return A.r<B.r;
    	}
    }q[N];
    struct data
    {
    	int x,y;
    	friend inline bool operator < (const data& A,const data& B)
    	{
    		return A.x>B.x;
    	}
    }p[50];
    int n,m,mx,tot,a[N],lst[N]; char ans[N][11];
    class FileInputOutput
    {
    	private:
    		static const int S=1<<21;
    		#define tc() (A==B&&(B=(A=Fin)+fread(Fin,1,S,stdin),A==B)?EOF:*A++)
    		char Fin[S],*A,*B;
    	public:
    		Tp inline void read(T& x)
    		{
    			x=0; char ch; while (!isdigit(ch=tc()));
    			while (x=(x<<3)+(x<<1)+(ch&15),isdigit(ch=tc()));
    		}
    		#undef tc
    }F;
    class TreeArray
    {
    	private:
    		int bit[N];
    		#define lowbit(x) (x&-x)
    	public:
    		inline void add(RI x,CI y)
    		{
    			for (;x;x-=lowbit(x)) bit[x]+=y;
    		}
    		inline int get(RI x,int y=0)
    		{
    			for (;x<=n;x+=lowbit(x)) y+=bit[x]; return y;
    		}
    		#undef lowbit
    }BIT[11];
    int main()
    {
    	//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
    	RI i; for (F.read(n),F.read(m),i=1;i<=n;++i) F.read(a[i]),mx=max(mx,a[i]);
    	for (i=1;i<=m;++i) F.read(q[i].l),F.read(q[i].r),q[i].id=i;
    	for (sort(q+1,q+m+1),tot=i=1;i<=n;++i)
    	{
    		RI cnt=0,j,fr=0,bk=0; for (j=max(1,a[i]-11);j<=min(mx,a[i]+11);++j)
    		if (lst[j]>lst[a[i]]) p[++cnt]=(data){lst[j],j}; p[++cnt]=(data){i,a[i]};
    		for (p[cnt+1].x=lst[a[i]],sort(p+1,p+cnt+1),j=1;j<=cnt;++j)
    		{
    			if (p[j].y<a[i]) while (fr<=10&&(a[i]-fr-1==p[j].y||lst[a[i]-fr-1]>p[j].x)) ++fr;
    			if (p[j].y>a[i]) while (bk<=10&&(a[i]+bk+1==p[j].y||lst[a[i]+bk+1]>p[j].x)) ++bk;
    			if (1<=fr&&fr<=10) BIT[fr].add(p[j].x,-1),BIT[fr].add(p[j+1].x,1);
    			if (1<=bk&&bk<=10) BIT[bk].add(p[j].x,-1),BIT[bk].add(p[j+1].x,1);
    			if (fr+bk+1<=10) BIT[fr+bk+1].add(p[j].x,1),BIT[fr+bk+1].add(p[j+1].x,-1);
    		}
    		lst[a[i]]=i; while (tot<=m&&q[tot].r==i)
    		{ for (j=1;j<=10;++j) ans[q[tot].id][j]=BIT[j].get(q[tot].l)%10+48; ++tot; }
    	}
    	for (i=1;i<=m;++i) puts(ans[i]+1); return 0;
    }
    
  • 相关阅读:
    【题解】「CF1373B」01 Game
    asdfasd
    android开发DialogFragment禁止按back键消失的解决方法
    MySQL报错1055
    IDEA中使用Git拉取代码时报 Git pull failed原因及处理方法
    数据挖掘导论 完整版+PPT+Python R代码
    MATLAB统计分析与应用 40个案例分析[源代码及数据]
    机器学习实战 中英文版
    电力系统负荷预测数据集【全】含下载链接
    Nginx 导致swagger setCookie sessionid 失效
  • 原文地址:https://www.cnblogs.com/cjjsb/p/12865120.html
Copyright © 2011-2022 走看看