zoukankan      html  css  js  c++  java
  • 【CometOJ】Comet OJ

    点此进入比赛

    (A):杀手皇后(点此看题面

    大致题意: 求字典序最小的字符串。

    一场比赛总有送分题。。。

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    using namespace std;
    int n;string s;
    int main()
    {
    	RI i;string st;for(cin>>n>>s,i=2;i<=n;++i) cin>>st,st<s&&(s=st,0);//读入,求字典序最小字符串
    	return cout<<s<<endl,0;//输出
    }
    

    (B):支援城市(点此看题面

    大致题意: 对于每个(x),求(sum_{i=1}^n(a_i-a_x)^2)

    拆平方得到:

    [sum_{i=1}^n(a_i^2-2a_ia_x+a_x^2)=sum_{i=1}^na_i^2-2a_xsum_{i=1}^na_i+na_x^2 ]

    不难发现,只要预处理出(sum_{i=1}^na_i^2)(sum_{i=1}^na_i),对于每个(x)就可以直接(O(1))计算了。

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 100000
    #define LL long long
    using namespace std;
    int n,a[N+5];
    int main()
    {
    	RI i;LL s=0,s2=0;for(scanf("%d",&n),i=1;i<=n;++i) scanf("%d",a+i),s+=a[i],s2+=1LL*a[i]*a[i];//预处理和及平方和
    	for(i=1;i<=n;++i) printf("%lld ",s2-2*s*a[i]+1LL*n*a[i]*a[i]);return 0;//计算答案并输出
    }
    

    (C):符文能量(点此看题面

    大致题意: 给你两个数组(a,b),可以选择一段区间([L,R]),使得(Lle ile R)的所有(a_i,b_i)都乘上(k),求(sum_{i=2}^nb_{i-1}a_i)的最小值。

    这可以直接(DP)

    我们设(f_i)表示选择包含(i)(i)不为结尾的一段区间所能得到的最小变化值。

    转移时分两种情况讨论,一种是(i)在区间内部,另一种是(i)为区间开头:

    [f_i=min(f_{i-1}+b_{i-1}a_i(k^2-1),b_{i-1}a_i(k-1)) ]

    同时我们每次要用以(i)为结尾的情况去更新最小变化值:

    [Mn=min(Mn,f_{i-1}+b_{i-1}a_i(k-1)) ]

    最终答案就是原先的答案加上最小变化值。

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 100000
    #define LL long long
    #define min(x,y) ((x)<(y)?(x):(y))
    #define Gmin(x,y) (x>(y)&&(x=(y)))
    using namespace std;
    int n,k,a[N+5],b[N+5];LL f[N+5];
    int main()
    {
    	RI i;LL Mn=0,ans=0;for(scanf("%d%d",&n,&k),i=1;i<=n;++i) scanf("%d%d",a+i,b+i);//读入
    	for(i=1;i<=n+1;++i) Gmin(Mn,f[i-1]+b[i-1]*a[i]*(k-1)),//更新最小变化值
    		ans+=b[i-1]*a[i],f[i]=min(b[i-1]*a[i]*(k-1),f[i-1]+b[i-1]*a[i]*(k*k-1));//计算原先答案,并动态规划转移f[i]
    	return printf("%lld",ans+Mn),0;//输出答案
    }
    

    (D):菜菜种菜(点此看题面

    大致题意: 给一张有向图,每次询问一个区间,求这个区间内不与区间内其他点直接相连的点的权值之和。

    我们定义(l_i)为与(i)相连的点中编号小于(i)的最大编号,(r_i)为与(i)相连的点中编号大于(i)的最小编号。

    设当前询问区间为([L,R]),那么一个点对一个询问有贡献,当且仅当其满足:

    [l_i<Lle ile R<r_i ]

    即:

    [l_i+1le Lle ile Rle r_i-1 ]

    那么我们就可以考虑离线,将询问对(L)排序。

    然后我们枚举(L),每次对于所有(l_i+1=L)(i),它们满足条件了,因此用树状数组维护,将(isim r_i-1)位置都加上(a_i)

    同时,(L-1)这个位置已不在询问范围内,因此我们把(L-1sim r_{L-1}-1)的位置都减去(a_{L-1})

    询问时只要询问(a_R)位置上的值即可。

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 1000000
    #define swap(x,y) (x^=y^=x^=y)
    #define Gmin(x,y) (x>(y)&&(x=(y)))
    #define Gmax(x,y) (x<(y)&&(x=(y)))
    using namespace std;
    int n,m,Qt,a[N+5],l[N+5],r[N+5],L[N+5],R[N+5];
    vector<int> s[N+5],q[N+5];vector<int>::iterator it;
    class FastIO
    {
    	private:
    		#define FS 100000
    		#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
    		#define tn (x<<3)+(x<<1)
    		#define D isdigit(c=tc())
    		char c,*A,*B,FI[FS];
    	public:
    		I FastIO() {A=B=FI;}
    		Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
    		Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
    }F;
    class TreeArray//树状数组
    {
    	private:
    		#define lowbit(x) (x&-x)
    		int v[N+5];
    		I void Upt(RI x,CI y) {W(x<=n) v[x]+=y,x+=lowbit(x);}//修改后缀
    	public:
    		I void Add(CI l,CI r,CI v) {Upt(l,v),Upt(r+1,-v);}//区间修改,差分
    		I int Qry(RI x,RI t=0) {W(x) t+=v[x],x-=lowbit(x);return t;}//单点询问
    }T;
    int main()
    {
    	RI i,x,y;long long ans=0;
    	for(F.read(n,m,Qt),i=1;i<=n;++i) F.read(a[i]),l[i]=0,r[i]=n+1;//初始化
    	for(i=1;i<=m;++i) F.read(x,y),x>y?Gmax(l[x],y):Gmin(r[x],y);//预处理l,r
    	for(i=1;i<=n;++i) s[l[i]].push_back(i);//对于l[i]开桶,方便后面的操作
    	for(i=1;i<=Qt;++i) F.read(L[i],R[i]),q[L[i]].push_back(i);//读入询问,并桶排
    	for(i=1;i<=n;++i)//枚举L
    	{
    		i^1&&(T.Add(i-1,r[i-1]-1,-a[i-1]),0);//删去L-1的贡献
    		for(it=s[i-1].begin();it!=s[i-1].end();++it) T.Add(*it,r[*it]-1,a[*it]);//对于所有l[i]+1=L的i,加上其贡献
    		for(it=q[i].begin();it!=q[i].end();++it) ans^=1LL*(*it)*T.Qry(R[*it]);//枚举R询问
    	}return printf("%lld",ans),0;
    }
    

    (E):神奇函数(点此看题面

    大致题意: (d(x))(x)大于(1)的最小因数,(f(x)=egin{cases}1 & x=1\d(x)f(frac x{d(x)^2}) & d(x)^2|x\f(frac x{d(x)}) & othersend{cases}),求(sum_{i=1}^nf(i))

    我们设(x=sum_{i=1}^tp_i^{c_i}),则(f(x)=sum_{i=1}^tp_i^{lfloorfrac {c_i}2 floor})。证明如下:

    对于一个(p_i),若(c_ige 2),则由(f(x)=d(x)f(frac x{d(x)^2}) (d(x)^2|x))就会消掉(x)中的两个(p_i),得到(f(x))中的(1)(p_i),即(c_i)个数除以(2)

    而若(c_i=1),则由(f(x)=f(frac x{d(x)}) others)就会把这一个(p_i)消掉,即除以二后向下取整。

    那么,(f(n))显然是(O(sqrt n))级别的。

    所以我们可以枚举(f(i)),设(g(x))表示(1sim n)内不含平方因子的数的个数,那么答案就是:

    [sum_{i=1}^{sqrt n}icdot g(lfloorfrac n{i^2} floor) ]

    其中(g)的意义在于,若一个数含有平方因子(k^2),那么它的(f)值就会是(ik),所以应不含平方因子。

    然后考虑(g)值的求法,这可以使用容斥,而容斥系数就是(mu)。所以:

    [g(x)=sum_{i=1}^{sqrt x}mu(i)lfloorfrac n{i^2} floor ]

    对于上面的答案以及这里的(g),我们都可以用除法分块来较快速地求值,但似乎会被卡。。。

    所以我们要预处理出(xle10^7)(g(x)),这样就能过了。

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define LS 10000000
    #define LL long long
    using namespace std;
    LL n;
    template<int SZ> class LinearSieve//线性筛
    {
    	private:
    		int Pt,P[SZ+5],mu[SZ+5];
    	public:
    		LL smu[SZ+5],smu2[SZ+5];
    		I LinearSieve()
    		{
    			RI i,j;for(mu[1]=1,i=2;i<=LS;++i)
    				for(!P[i]&&(mu[P[++Pt]=i]=-1),j=1;j<=Pt&&1LL*i*P[j]<=SZ;++j)
    					if(P[i*P[j]]=1,i%P[j]) mu[i*P[j]]=-mu[i];else break;
    			for(i=1;i<=LS;++i) smu[i]=smu[i-1]+mu[i],smu2[i]=smu2[i-1]+mu[i]*mu[i];//筛mu和以及平方和
    		}
    };LinearSieve<LS> L;
    I LL G(Con LL& x)
    {
    	if(x<=LS) return L.smu2[x];RI l,r,sx=sqrt(x);LL res=0;//x较小时直接返回答案
    	for(l=1;l<=sx;l=r+1) r=sqrt(x/(x/(1LL*l*l))),res+=x/(1LL*l*l)*(L.smu[r]-L.smu[l-1]);//除法分块
    	return res;//返回答案
    }
    int main()
    {
    	RI Tt,l,r,sn;LL ans=0;scanf("%d",&Tt);W(Tt--)
    	{
    		scanf("%lld",&n),sn=sqrt(n),ans=0;//读入
    		for(l=1;l<=sn;l=r+1) r=sqrt(n/(n/(1LL*l*l))),ans+=G(n/(1LL*l*l))*(l+r)*(r-l+1)>>1;//除法分块
    		printf("%lld
    ",ans);//输出答案
    	}return 0;
    }
    

    (F):黄金体验(占坑待填)

  • 相关阅读:
    【LayUi】表格中显示图片
    【LayUi】laydate.render报错:日期格式不合法
    【C#】日期格式化(关于12小时制和24小时制)
    【JavaScript】for循环使用splice()方法
    【LayUi】 动态table操作:edit、switch、tool、checkbox
    【LayUi】vue绑定数据随笔
    【LayUi】中国省市复选框
    【LayUi】动态数据表格+分页+CheckBox
    【LayUi】下拉框
    SQL Server自动生成存储过程(Insert,Update)
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/CometOJContest8.html
Copyright © 2011-2022 走看看