Codeforces Round #613 (Div. 2)
D. Dr. Evil Underscores
題意很簡單:
就是這麼簡單的題意我還看錯題了,我以爲是求X。。。然後就不可做了。
然而題目是求
這個,最大值中的最小值。。
那就可做了。有一道類似的題:143. 最大異或對(字典樹)acwing 一樣的思路
具體做法就是 在二進制字典樹上跑dfs,當 當前節點既有0,又有1時,那麼ans這位上一定是1,否則就是0。。。直接dfs跑一遍字典樹即可。。。我感覺我像個傻子一樣,老看錯題。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=(b);++i)
#define mem(a,x) memset(a,x,sizeof(a))
#define pb push_back
#define pi pair<int, int>
#define mk make_pair
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const ll inf=0x3f3f3f3f3f3f3f3f;
const int N=1e5+10;
int a[N],n,ans,cnt;
int ne[N*35][2];
void dfs(int o,int id,int val)
{
if(id<0) {
ans=min(ans,val);
return ;
}
if(ne[o][0]&&ne[o][1]){
dfs(ne[o][0],id-1,val^(1<<id));
dfs(ne[o][1],id-1,val^(1<<id));
}
else if(ne[o][1]) dfs(ne[o][1],id-1,val);
else dfs(ne[o][0],id-1,val);
}
void in(int x)
{
int id=0;
for(int i=30;~i;--i){
int to=0;
if(x&(1<<i)){
to=1;
}
if(!ne[id][to]){
ne[id][to]=++cnt;
}
id=ne[id][to];
}
}
int main()
{
cin>>n;
rep(i,1,n) {
scanf("%d",&a[i]);
in(a[i]);
}
ans=1<<30;
dfs(0,30,0);
printf("%d\n",ans);
}
E. Delete a Segment
很妙的做法~
/*
區間查詢被覆蓋的區間有多少個連續的一段1
*/
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int sum[10*N],add[10*N],X[10*N],len,b[N];
struct node
{
int l,r;
}a[N];
int n;
void init(int len)
{
for(int i=0;i<=len;++i){
add[i]=sum[i]=0;
}
}
int getid(int x)
{
return lower_bound(X+1,X+1+len,x)-X;
}
int main()
{
int _;cin>>_;while(_--){
scanf("%d",&n);
len=0;
for(int i=1;i<=n;++i){
scanf("%d%d",&a[i].l,&a[i].r);
a[i].l=2*a[i].l,a[i].r=a[i].r*2;
X[++len]=a[i].l-1;X[++len]=a[i].l;X[++len]=a[i].l+1;
X[++len]=a[i].r-1;X[++len]=a[i].r;X[++len]=a[i].r+1;
}
sort(X+1,X+1+len);
len=unique(X+1,X+1+len)-X-1;
init(len);
for(int i=1;i<=n;++i){
a[i].l=getid(a[i].l);a[i].r=getid(a[i].r);
//printf("l:%d r:%d\n",a[i].l,a[i].r);
add[a[i].l]++;add[a[i].r+1]--;
}
int pre=0;
for(int i=1;i<=len;++i){
pre+=add[i];
b[i]=pre;
}
for(int i=1;i<=len;++i){
if(b[i]==1&&b[i-1]!=1) sum[i]=sum[i-1]+1;
else sum[i]=sum[i-1];
//printf("%d ",b[i]);
}
//puts("");
pre=0;
for(int i=1;i<=len;++i){
if(b[i]==0&&b[i-1]!=0) pre++;
}
int ans=pre-1;
for(int i=1;i<=n;++i){
int t=sum[a[i].r]-sum[a[i].l-1];
if(b[a[i].l-1]==0&&b[a[i].l]==1) t--;
if(b[a[i].r+1]==0&&b[a[i].r]==1) t--;
ans=max(ans,t+pre);
}
printf("%d\n",ans);
}
}