6.6总结
Posted zzqdeco
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了6.6总结相关的知识,希望对你有一定的参考价值。
考试考到一半还不知道是不是对的就来写题解了
t1
首先想到异或,因为相同的两个数一定异或过后为0
然后发现得到最后两个数的异或值仿佛也没用啊
便随手就是一个暴力map(测了一下内存大概是16MB,有点难受
于是想想怎么解决有异或值也没法确定的问题
便考虑到了,对于都有同一个位的数来异或,则有三种情况
-
为0,不能说明什么,两个不同的数没有这个位
-
为异或和,两个不同的数都有这个数
-
都不是,那么剩下的就是ans之一
所以应该是a了,时间复杂度 (O(nlogn))
#include<cstdio>
#include<iostream>
using namespace std;
int sum,n;
int wei[40];
int main()
{
scanf("%d",&n);
for(int i=1;i<=2*n;i++)
{
int now;
scanf("%d",&now);
sum^=now;
for(int j=0;j<31;j++)
{
if(now&(1<<j))
{
wei[j]^=now;
}
}
}
for(int j=0;j<31;j++)
{
if(sum!=wei[j]&&wei[j])
{
printf("%d %d",wei[j],sum^wei[j]);
return 0;
}
}
}
t2
说巧不巧,cf上一次真好做过差不多的题
一开始感觉是数据结构,但是考虑到这个信息不好处理
势能分析?我估计mzoj不会考这种东西
所以显然我觉得是一个和p有关的东西,因为只有p比较小的说
所以我就考虑到为0的条件,突然间想到了鸽巢原理,但这个的贪心正确性不会证明啊,只是上次cf大胆用了一下对了
那么显然我既然cf过了,那么这个结论就是莓问题的
那就是在前面是1时是最坏情况
所以大于p的话一定为0,由此我只用考虑小于p的情况
那么复杂度就出来了,(O(n*q^2)),但是好像时间有点悬(两秒刚刚能过?
#include <cstdio>
#include <iostream>
using namespace std;
int n,m;
long long a[100010],sum[100010],ans,maxn=0x3f3f3f3f;
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
sum[i]=sum[i-1]+a[i];
}
for(int i=1;i<=m;i++)
{
long long nowl,nowr,nowp;
scanf("%lld%lld%lld",&nowl,&nowr,&nowp);
if(nowr-nowl>nowp)
{
printf("0
");
continue;
}
ans=nowp;
for(int l=nowl;l<=nowr;l++)
{
for(int r=l;r<=nowr;r++)
{
ans=min(ans,(sum[r]-sum[l-1])%nowp);
}
}
printf("%lld
",ans);
}
}
T3
感觉一开始想网络流的我真的是傻了
(n)明明就不是和人数相关的,而且也没有说一个人一个吃的
所以
这种最大值最小考虑函数求值的二分和三分吧
于是盲猜三分性质,打了一个三分套三分(希望不要爆零)
复杂度(nlog^2n)
#include <iostream>
#include <algorithm>
using namespace std;
struct wee
{
long long a,b,c;
}d[100010];
int n;
bool cmp(wee a,wee b)
{
if(a.a==b.a)
{
if(a.b==b.b)
{
return a.c<b.c;
}
else return a.b<b.b;
}
else return a.a<b.a;
}
long long can_do(long long a,long long b)
{
long long ans=0;
for(int i=1;i<=n;i++)
{
if(d[i].a>a&&d[i].b>b)
{
ans=max(ans,d[i].c);
}
}
return ans+a+b;
}
long long check(long long a)
{
long long l=0,r=a;
while(l<r)
{
long long mid1=l+(r-l)/3,mid2=r-(r-l)/3;
if(can_do(mid1,a-mid1)<can_do(mid2,a-mid2))
{
r=mid2-1;
}
else
{
l=mid1+1;
}
}
return can_do(l,a-l);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld%lld%lld",&d[i].a,&d[i].b,&d[i].c);
}
long long l=0,r=200000001;
while(l<r)
{
long long mid1=l+(r-l)/3,mid2=r-(r-l)/3;
if(check(mid1)<check(mid2)) r=mid2-1;
else l=mid1+1;
}
printf("%lld
",check(l));
}
以上是关于6.6总结的主要内容,如果未能解决你的问题,请参考以下文章