【LGR-069】洛谷 2 月月赛 II & EE Round 2

前言

T1传送门T2传送门T3传送门T4传送门T5传送门T6传送门
T6放弃,T4博客在这里
考场310的菜鸡瑟瑟发抖


洛谷 6101 [EER2]出言不逊

分析

设字符串长度为\(Len\)
每次显然我会挑长度最大的复制一倍,那么最大的复制一倍后还是最大的
设最大的长度为\(x\),那么显然要满足一个不等式
\(Len+\sum_{j=1}^{k}2^jx\geq L\)
\(k\)也就是答案,那不就是暴力吗
(唯一比较坑的就是\(\text{unsigned long long}\)


代码

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
int cnt[62],len,ans; unsigned long long L,big;
signed main(){
	rr char c=getchar();
	while (!isalnum(c)) c=getchar();
	while (isalnum(c)){
        if (isdigit(c)) ++cnt[c^48];
        else if (islower(c)) ++cnt[c-87];
            else ++cnt[c-29];
        c=getchar(),++len;
	}
	scanf("%llu",&L);
	for (rr int i=0;i<62;++i) big=big<cnt[i]?cnt[i]:big;
	while (L>len){
		++ans;
		if (L<big) break;//变成负数会溢出
		L-=big,big<<=1;
	}
	return !printf("%d",ans);
}

洛谷 6102 [EER2]谔运算

分析

考虑怎样能对答案产生贡献
首先位运算显然可以拆位算
可以统计\(cnt[x]\)表示二进制第\(x\)位为1的数的个数
\(\text{xor}\)为1当且仅当一个为0一个为1
那么分类讨论
\(\text{or}=1,\text{and}=0\)
\(\text{or}\)考虑容斥,用总答案减去不合法的
\(n^2-(n-cnt_x)^2=(n*2-cnt_x)*cnt_x\)
\(\text{and}=0\),同样的道理
\(n^2-cnt_x^2=(n+cnt_x)*(n-cnt_x)\)
\(\text{or}=0,\text{and}=1\)
\((n-cnt_x)^2+cnt_x^2\)
两种答案加起来,再拆开式子就是代码所示


代码

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
typedef unsigned uit;
uit n,cnt[32],ans;
inline uit iut(){
	rr uit ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
signed main(){
	n=iut();
	for (rr uit i=1;i<=n;++i)
	for (rr uit t=0,x=iut();x;x>>=1)
	    cnt[t++]+=x&1;
	for (rr uit i=0,t=1;i<32;++i,t<<=1)
	    ans+=t*cnt[i]*(n-cnt[i])*2*(cnt[i]*n-cnt[i]*cnt[i]+n*n);
	return !printf("%u",ans);
}

洛谷 6103 [EER2] 直接自然溢出啥事没有

分析

按照题意dp可以获零分的高分
为什么呢
考虑函数变成值有两种方式
所以要去重
但是不算哪个呢
当然是不算函数变成值啦
WA多次


代码

#include <cstdio>
#include <cctype>
#define rr register
using namespace std;
typedef unsigned long long ull;
ull f[10011][5],n;
signed main(){
	scanf("%llu",&n);
	f[0][0]=f[1][0]=f[1][2]=1;
	for (rr int i=2;i<=n;++i){
        f[i][1]=f[i-2][0];
        f[i][2]=f[i][1]+f[i-1][4];
        f[i][3]=f[i-2][3]+f[i-2][1]+(i>4)*f[i-4][1];
        f[i][4]=f[i][3]+f[i-2][4];
		for (rr int j=0;j<i;++j)
		    f[i][0]+=f[j][0]*f[i-j][2];
	}
	return !printf("%llu",f[n][0]);
}

洛谷 6105 [Ynoi2010] iepsmCmq

分析

分类讨论,如果\(C<i+j<2C\),显然只需要取最大值和次大值加起来
否则\(0<i+j<C\)那么用一个\(\text{STL::multiset}\)
特别注意找到的答案需要判断与之前的配对答案关系


代码

#include <cstdio>
#include <cctype>
#include <set>
#define rr register
using namespace std;
int mod,tot,Q; multiset<int>uk,S;
multiset<int>::iterator it;
inline signed iut(){
	rr int ans=0,f=1; rr char c=getchar();
	while (!isdigit(c)) f=(c=='-')?-f:f,c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans*f;
}
inline void print(int ans){
	if (ans>9) print(ans/10);
	putchar(ans%10+48);
}
inline signed max(int a,int b){return a>b?a:b;}
inline signed Get(int x,bool nx){
	if (x==-1) return -1;
	it=uk.lower_bound(mod-x);
	if (it==uk.begin()) return -1; --it;
	if (nx&&*it==x&&uk.count(x)==1)
	    return it==uk.begin()?-1:*--it;
	else return *it;
}
inline void Add(int x){
	if (++tot==1) {uk.insert(x); return;}
	rr int fi=Get(x,0),se=Get(fi,1),th=Get(se,1);
	if (fi!=-1&&se<x){
		if (se!=-1&&fi==th) S.erase(S.find(fi+se));
		S.insert(x+fi);
	}
	uk.insert(x);
}
inline void Del(int x){
	uk.erase(uk.find(x)),--tot;
	if (!tot) return;
	rr int fi=Get(x,0),se=Get(fi,1),th=Get(se,1);
	if (fi!=-1&&se<x){
		if (se!=-1&&fi==th) S.insert(fi+se);
		S.erase(S.find(x+fi));
	}
}
inline signed query(){
	rr int ans=S.empty()?0:(*--S.end());
	it=--uk.end();
	if (uk.count(*it)>1) ans=max(ans,*it*2%mod);
	    else {
	    	rr int t=*it; --it;
	    	ans=max(ans,(*it+t)%mod);
		}
	return ans;
}
signed main(){
	Q=iut(),mod=iut();
	for (rr int opt,x,lans=0;Q;putchar(10),--Q){
		opt=iut(),x=(iut()^lans)%mod;
		if (opt==1) Add(x); else Del(x);
		if (tot>1) print(lans=query());
		    else putchar(69),putchar(69),lans=0;
	}
	return 0;
}
posted @ 2020-02-22 20:11  lemondinosaur  阅读(315)  评论(0编辑  收藏  举报