zoukankan      html  css  js  c++  java
  • P4692 [Ynoi2016] 谁的梦

    P4692 [Ynoi2016] 谁的梦(set)

    首先正难则反是必须想到的,我们可以考虑先不管所有的值,把全部值都作为答案统计一边,然后减去贡献即可。

    重点在于怎么减去贡献,容易发现,我们这样做其实就是把每个序列分成了很多段,于是我们考虑用 set 维护每一个断点的前驱后继,然后暴力算答案即可。

    注意有一个坑点是 0 没用逆元,必须特判。

    时间复杂度 (O(nlogn))

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    template <typename T>
    inline void read(T &x){
    	x=0;bool f=false;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-'){f=true;}ch=getchar();}
    	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    	x=f?-x:x;
    	return ;
    }
    template <typename T>
    inline void write(T x){
    	if(x<0) putchar('-'),x=-x;
    	if(x>9) write(x/10);
    	putchar(x%10^48);
    	return ;
    }
    #define int long long
    const int N=2e5+5,MOD=19260817;
    int n,m,len[N],tot2,res,sum1[N],sum2[N],Cnt[N],tot,Sum;
    vector<int>p[N];
    map<int,int> Map;
    map<pair<int,int>,int> Map2;
    set<int>st[N*5];
    set<int>::iterator it,IT;
    int QuickPow(int x,int y,int res=1){for(;y;y>>=1,x=x*x%MOD)if(y&1)res=res*x%MOD;return res;}
    int Getpos(int x){if(Map.find(x)==Map.end())sum1[Map[x]=++tot]=Sum;return Map[x];}
    int GetPos(int x,int y) {
    	if(Map2.find(make_pair(x,y))==Map2.end()){
    		st[Map2[make_pair(x,y)]=++tot2].insert(0),st[tot2].insert(len[y]+1);
    		sum2[tot2]=(len[y]*(len[y]+1)>>1)%MOD;
    	}
    	return Map2[make_pair(x,y)];
    }
    void Insert(int c,int x,int now){
    	res-=Sum-((!Cnt[c])?sum1[c]:0);
    	if(!sum2[x]) Cnt[c]--;
    	else sum1[c]=sum1[c]*QuickPow(sum2[x],MOD-2)%MOD;
    	it=st[x].lower_bound(now),IT=--it,++it;
    	sum2[x]=(sum2[x]-((*it-*IT)*(*it-*IT-1)>>1))%MOD;
    	sum2[x]=(sum2[x]+((now-*IT)*(now-*IT-1)>>1))%MOD;
    	sum2[x]=(sum2[x]+((*it-now)*(*it-now-1)>>1)+MOD)%MOD;
    	if(!sum2[x])++Cnt[c];
    	else sum1[c]=sum1[c]*sum2[x]%MOD;
    	res+=Sum-((!Cnt[c])?sum1[c]:0),st[x].insert(now);
    	return ;
    }
    void Delete(int c,int x,int now){
    	res-=Sum-((!Cnt[c])?sum1[c]:0);
    	if(!sum2[x]) Cnt[c]--;
    	else sum1[c]=sum1[c]*QuickPow(sum2[x],MOD-2)%MOD;
    	st[x].erase(now),it=st[x].lower_bound(now),IT=--it,++it;
    	sum2[x]=(sum2[x]-((now-*IT)*(now-*IT-1)>>1))%MOD;
    	sum2[x]=(sum2[x]-((*it-now)*(*it-now-1)>>1))%MOD;
    	sum2[x]=(sum2[x]+((*it-*IT)*(*it-*IT-1)>>1)+MOD+MOD)%MOD;
    	if(!sum2[x]) Cnt[c]++;
    	else sum1[c]=sum1[c]*sum2[x]%MOD;
    	res+=Sum-((!Cnt[c])?sum1[c]:0);
    	return ;
    }
    signed main() {
    	read(n),read(m),Sum=1;
    	for(int i=1;i<=n;i++) read(len[i]),Sum=(len[i]*(len[i]+1)>>1)%MOD*Sum%MOD,p[i].resize(len[i]+2);
    	for(int i=1;i<=n;i++) for(int j=1;j<=len[i];j++) read(p[i][j]);
    	for(int i=1;i<=n;i++) for(int j=1;j<=len[i];j++) Insert(Getpos(p[i][j]),GetPos(p[i][j],i),j);
    	res=(res%MOD+MOD)%MOD;
    	write(res),putchar('
    ');
    	for(int i=1,x,y,z;i<=m;i++){
    		read(x),read(y),read(z);
    		Delete(Getpos(p[x][y]),GetPos(p[x][y],x),y),p[x][y]=z;
    		Insert(Getpos(p[x][y]),GetPos(p[x][y],x),y);
    		res=(res%MOD+MOD)%MOD;
    		write(res),putchar('
    ');
    	}
    	return 0;
    }
    
  • 相关阅读:
    前端 时间个性化 插件 jquery.timeago.js
    IP釋放、清除、以及刷新DNS
    Visual Studio 2019 16.0 正式版下载
    handlebars.js 用 <br>替换掉 内容的换行符
    c#-SimHash匹配相似-算法
    索尼Sony ATI显卡驱动 Win7 Win8 Win8.1 视频黑屏 解决方法
    c#-冒泡排序-算法
    c#-二分查找-算法
    c#-快速排序-算法
    win8.1中安装sql2014 0x800F0906 【 Error while enabling Windows feature : NetFx3, Error Code : -2146498298 】
  • 原文地址:https://www.cnblogs.com/Akmaey/p/14667382.html
Copyright © 2011-2022 走看看