K
题意: 给定n次位运算,包括&、|、^.给定q次询问,每次可以选择[0,r]中的任意整数x,令x经过这n次位运算最大,输出选择的x.
思路: 贪心。比较套路的题,这n次位运算是独立的,可以对于每一位提前预处理出来,以0和1为起点能否变成1. 然后对于每次查询,从高位到低位处理,如果0能变成1直接这一位填0,如果1才能变成1在满足限制的前提下这一位填1,二进制特性,这一位选1比后边所有位都选1更优。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
int n,m,k,T;
struct node{
int op;
int x;
}a[N];
bool vis[33][2];
void solve()
{
int q;
scanf("%d%d",&n,&q);
for(int i=0;i<n;++i)
{
int op,x;
scanf("%d%d",&op,&x);
a[i] = {op,x};
}
for(int k=29;k>=0;--k) //ö�ٵ�kλΪ0����1�����
{
for(int i=0;i<=1;++i) //0��1
{
int now = 0;
if(i==0) now = 0;
else now = (1<<k);
for(int j=0;j<n;++j)
{
int op = a[j].op;
int x = a[j].x;
if(x>>k&1) x = (1<<k);
else x = 0;
if(op==1) now &= x;
else if(op==2) now |= x;
else now ^= x;
}
if(now==(1<<k)) vis[k][i] = 1;
}
}
while(q--)
{
int mx; scanf("%d",&mx);
int ans = 0;
int cost = 0;
for(int i=29;i>=0;--i)
{
if(vis[i][0])
{
// cout<<i<<"??\n";
ans = ( ans | (1<<i) );
}
else if(vis[i][1])
{
int tmp = (1<<i);
if(cost+tmp<=mx) cost = cost + tmp;
}
}
printf("%d\n",cost);
}
}
signed main(void)
{
solve();
return 0;
}
G
题意: 给定n层的树,第i层有i个叶子,类似数字三角形。起始所有叶子都是红的,有若干个叶子被染黑了。所有染黑的叶子的左右两儿子都会黑,如果相邻两个叶子都黑,他们上边的叶子也会黑。
思路: 如果某个叶子染黑,他可以一直扩展到第n层。最后的结果会是若干个互不相交的三角形,每个三角形的贡献是n*(n+1)/2。在第n层用差分维护,即可获得对应的三角形,统计答案。记得关流,不然输入就T了,麻。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6+10;
int b[N];
int n,m,k,T;
void solve()
{
cin>>n>>k;
while(k--)
{
int i,j; cin>>i>>j;
int l = j;
int r = j+n-i;
b[l]++,b[r+1]--;
}
for(int i=1;i<=n;++i) b[i] += b[i-1];
int now = 0; ll ans = 0;
for(int i=1;i<=n;++i)
{
// cout<<i<<":"<<b[i]<<"\n";
if(b[i]>0) now++;
else ans += 1ll*now*(now+1)/2,now = 0;
}
if(now) ans += 1ll*now*(now+1)/2,now = 0;
cout<<ans;
}
signed main(void)
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
solve();
return 0;
}
I
题意: 给定x、y、z,x和y都有a个1、b个0,z有c个0. 满足y<=x,z=x-y。构造合法的x、y.
思路:
1 … 0
0 … 1
其余的1分别对应,做差的时候就可以忽略了。
令n=a+b,这样一做差就是n-1个1了。之后每次可以把最后的0和1都提前,每提前1位就减少1个1.
所以0到n-1个1都能变。
PS: 注意特判a、b、c为0的特殊情况
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5+10;
int n,m,k,T;
void solve()
{
int a,b,c; cin>>a>>b>>c;
n = a+b;
if(c==0)
{
for(int i=0;i<a;++i) cout<<1; for(int i=0;i<b;++i) cout<<0;
cout<<"\n";
for(int i=0;i<a;++i) cout<<1; for(int i=0;i<b;++i) cout<<0;
return ;
}
if(a==0||b==0)
{
cout<<-1; return ;
}
if(c<=n-1)
{
vector<int> va(n),vb(n);
va[0] = 1;
vb[0] = 0;
// int wh = (n-1)-c; //ƫ��.wh=0˵������Ӧ��λ��Ϊ���һλ��wh=1˵���ڵ�����2λ
int idx = c;
va[idx] = 0,vb[idx] = 1;
int cnt1 = a-1,cnt0 = b-1;
for(int i=1;i<n;++i)
{
if(i==idx) continue;
if(cnt1)
{
cnt1--; va[i] = vb[i] = 1;
continue;
}
if(cnt0)
{
cnt0--; va[i] = vb[i] = 0;
continue;
}
}
for(int i=0;i<n;++i) cout<<va[i];
cout<<"\n";
for(int i=0;i<n;++i) cout<<vb[i];
}
else cout<<-1;
}
signed main(void)
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
solve();
return 0;
}