• [ASDFZ]序列&计数


    序列

    Description
    初始时你有一个长度为\(n\)的序列,序列中的第\(i\)个数为\(i\).依次进行\(m\)次操作,每次操作给定正整数\(x_i\),你需要将当前序列无限循环后截取前\(x_i\)位作为新序列.
    你需要求出所有操作完成后序列中\(1\)\(n\)的个数.
    Input
    第一行两个正整数\(n,m\).
    第二行\(m\)个正整数\(x_1\)~\(x_m\).
    Output
    输出一行\(n\)个整数表示答案.
    Sample Input

    5 3
    6 8 13
    

    Sample Output

    4 3 2 2 2
    

    HINT
    \(1\leq{n,m}\leq10^5,1\leq{x_i}\leq10^{18}\)
    Solution

    100分

    显然,若\(i<j\)\(x_i\geq{x_j}\),则操作\(i\)没有用,单调栈求出所有有用的操作,\(x_i\)递增.
    \(i\)次操作后序列的前\(k\)位=第\(i-1\)次操作后序列\(\times\lfloor\frac{x_i}{x_{i-1}}\rfloor+\)\(i-1\)次操作后序列的前\(x_i\;mod\;x_{i-1}\)位.
    逆序处理操作.
    \(f[i]\)表示第\(i\)个序列被取到的次数.
    \(s[i]\)表示\(1\)~\(i\)这个整体取到的次数.
    每次二分\(\leq{k}\)的第一个\(x_i\),便可以在\(O(logn)\)的时间内得到解决.

    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define N 100005
    #define min(a,b) (a<b?a:b)
    #define max(a,b) (a>b?a:b)
    using namespace std;
    typedef long long ll;
    int n,m,t;
    ll x[N],f[N],s[N],q[N];
    inline int read(){
    	int ret=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)){
    		ret=(ret<<1)+(ret<<3)+c-'0';
    		c=getchar();
    	}
    	return ret;
    }
    inline ll rd(){
    	ll ret=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)){
    		ret=(ret<<1ll)+(ret<<3ll)+c-'0';
    		c=getchar();
    	}
    	return ret;
    }
    inline int chk(ll k,int r){
    	if(k<=q[1]) return 0;
    	int l=1,mid;
    	while(l<r){
    		mid=(l+r+1)>>1;
    		if(q[mid]<=k) l=mid;
    		else r=mid-1;
    	}
    	return l;
    }
    inline void Aireen(){
    	n=read();m=read();
    	for(int i=1;i<=m;++i) x[i]=rd();
    	q[++t]=n;
    	for(int i=1;i<=m;++i){
    		while(t&&x[i]<=q[t]) --t;
    		q[++t]=x[i];
    	}
    	f[t]=1ll;
    	for(int i=t,j;i;--i){
    		while((j=chk(q[i],i-1))){
    			f[j]+=q[i]/q[j]*f[i];
    			q[i]%=q[j];
    		}
    		s[q[i]]+=f[i];
    	}
    	for(int i=n-1;i;--i)
    		s[i]+=s[i+1];
    	for(int i=1;i<=n;++i)	
    		printf("%lld ",s[i]);
    	printf("\n");
    }
    int main(){
    	freopen("sequence.in","r",stdin);
    	freopen("sequence.out","w",stdout);
    	Aireen();
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    

    计数

    Description
    给定一个长度为\(n\)的序列\(x\),你需要求出有多少组\((a,b,c,d)\)满足\(1\leq{a}\leq{b}<c\leq{d}\leq{n}\)\(min(x_a,\dots,x_b)\leq{min(x_c,\dots,x_d)}\).
    Input
    第一行一个正整数\(n\).
    第二行\(n\)个正整数\(x_1,\dots,x_n\).
    Output
    一行一个整数表示答案,对\(998244353\)取模.
    Sample Input

    10
    8 2 4 3 5 3 1 5 8 3
    

    Sample Output

    235
    

    HINT
    \(n\leq500000,1\leq{x_i}\leq{10^9}\).
    Solution

    100分

    \(l_i,r_i\)表示\(i\)向左/右能扩展到最远的满足区间最小值\(<x_i/\leq{x_i}\)的下标.

    \(r_i,l_j\)的大小关系分类讨论.

    \(r_i<l_j\)时,方案数为\((i-l_i+1)\times(r_i-i+1)\times(j-l_j+1)\times(r_j-j+1)\).

    \(r_i\geq{l_j}\)时由于\(x_i<x_j\),容易证明\(l_i\leq{i}<l_j\leq{j}\leq{r_j}\leq{r_i}\),方案数为\((i-l_i+1)\times(r_j-j+1)\times[(l_j-i)\times(j-l_j+1)+C_{j-l_j+1}^2]\).

    两种情况的分界点为\(r_i\),用差分的思想,树状数组维护即可.

    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    #define N 500005
    #define M 998244353
    #define min(a,b) (a<b?a:b)
    #define max(a,b) (a>b?a:b)
    using namespace std;
    int q[N],t;
    int s1[N],s2[N],s3[N];
    int x[N],p[N],l[N],r[N],n,m,ans;
    inline int read(){
    	int ret=0;char c=getchar();
    	while(!isdigit(c)) c=getchar();
    	while(isdigit(c)){
    		ret=(ret<<1)+(ret<<3)+c-'0';
    		c=getchar();
    	}
    	return ret;
    }
    inline int lowbit(int x){
    	return x&(-x); 
    }
    inline void add1(int x,int k){
    	for(int i=x;i<=n;i+=lowbit(i))
    		s1[i]=(s1[i]+k)%M;
    }
    inline void add2(int x,int k){
    	for(int i=x;i<=n;i+=lowbit(i))
    		s2[i]=(s2[i]+k)%M;
    }
    inline void add3(int x,int k){
    	for(int i=x;i<=n;i+=lowbit(i))
    		s3[i]=(s3[i]+k)%M;
    }
    inline int ask1(int x){
    	int ret=0;
    	for(int i=x;i;i-=lowbit(i))
    		ret=(ret+s1[i])%M;
    	return ret; 
    }
    inline int ask2(int x){
    	int ret=0;
    	for(int i=x;i;i-=lowbit(i))
    		ret=(ret+s2[i])%M;
    	return ret; 
    }
    inline int ask3(int x){
    	int ret=0;
    	for(int i=x;i;i-=lowbit(i))
    		ret=(ret+s3[i])%M;
    	return ret; 
    }
    inline bool cmp(int x,int y){
    	return r[x]<r[y];
    }
    inline void Aireen(){
    	n=read();
    	for(int i=1;i<=n;++i)
    		p[i]=x[i]=read();
    	sort(p+1,p+1+n);
    	m=unique(p+1,p+1+n)-p-1;
    	for(int i=1;i<=n;++i) 
    		x[i]=lower_bound(p+1,p+1+m,x[i])-p;
    	for(int i=1;i<=n;++i){
    		while(t&&x[i]<x[q[t]]) --t;
    		if(t) l[i]=q[t]+1;
    		else l[i]=1;
    		q[++t]=i;
    	}
    	t=0;
    	for(int i=n;i;--i){
    		while(t&&x[i]<=x[q[t]]) --t;
    		if(t) r[i]=q[t]-1;
    		else r[i]=n;
    		q[++t]=i;
    	}
    	for(int i=1;i<=n;++i) p[i]=i;
    	sort(p+1,p+1+n,cmp);
    	for(int i=1,j=1;i<=n;++i){
    		while(j<=n&&r[p[j]]+1==i){
    			add1(x[p[j]],-(p[j]-l[p[j]]+1));
    			add2(x[p[j]],-1ll*(p[j]-l[p[j]]+1)*(-p[j])%M);
    			add3(x[p[j]],1ll*(p[j]-l[p[j]]+1)*(r[p[j]]-p[j]+1)%M);
    			++j;
    		}
    		ans=(ans+1ll*ask1(x[i])*(i-l[i]+1)%M*l[i]%M*(r[i]-i+1)%M)%M;
    		ans=(ans+1ll*ask2(x[i])*(i-l[i]+1)%M*(r[i]-i+1)%M)%M;
    		ans=(ans+1ll*ask1(x[i])*(1ll*(i-l[i]+1)*(i-l[i])/2%M)%M*(r[i]-i+1)%M)%M;
    		ans=(ans+1ll*ask3(x[i])*(i-l[i]+1)%M*(r[i]-i+1)%M)%M;
    		add1(x[i],i-l[i]+1);
    		add2(x[i],1ll*(i-l[i]+1)*(-i)%M);
    	}
    	printf("%d\n",(ans+M)%M);
    }
    int main(){
    	freopen("count.in","r",stdin);
    	freopen("count.out","w",stdout);
    	Aireen();
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    

    2017-04-05 23:39:02

  • 相关阅读:
    pytorch的函数中的group参数的作用
    pytorch的函数中的dilation参数的作用
    resnet18全连接层改成卷积层
    Pytorch实现UNet例子学习
    MyEclipse中出现Address already in use:JVM_Bind:8080
    为SQL数据库创建登录名和密码
    集合体系
    排序算法及其java实现
    java泛型通配符?
    Arrays.asList的用法
  • 原文地址:https://www.cnblogs.com/AireenYe/p/15609366.html
Copyright © 2020-2023  润新知