C. World of Darkraft: Battle for Azathoth
题意:有n把武器,m件盔甲,每件武器有攻击力Ai和价格CAi,每件盔甲有防御力Bj和价格CBj,现需购买一把武器和一副盔甲。 另外有p个怪,每个怪有防御力Xk、攻击力Yk以及击杀奖励Zk,一个怪被击杀当且仅当 购买武器的攻击力大于怪物 防御力,盔甲防御力大于怪物攻击力,即Ai > Xk 且 Bj >Yk,问最大收益。
题解:。。将每把武器的初始收益置为-CAi,然后按防御力小到大枚举每件盔甲,同时双指针不断更新攻击力小于当前盔甲防御力的怪k,那么攻击力大于Xk的武器收益都会增加 Zk,答案就是武器收益-盔甲价格的最大值。。。所以线段树区间覆盖维护最大值。。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll ma[1000000],lazy[1000000];
void down(int x){
if(lazy[x]){
ma[x*2]+=lazy[x];
lazy[x*2]+=lazy[x];
ma[x*2+1]+=lazy[x];
lazy[x*2+1]+=lazy[x];
lazy[x]=0;
}
}
void update(int root,int l,int r,int L,int R,int v){
if(l==L&&r==R){
lazy[root]+=v;
ma[root]+=v;
return;
}
down(root);
int mid=(l+r)/2;
if(R<=mid) update(root*2,l,mid,L,R,v);
else if(L>mid) update(root*2+1,mid+1,r,L,R,v);
else{
update(root*2,l,mid,L,mid,v);
update(root*2+1,mid+1,r,mid+1,R,v);
}
ma[root]=max(ma[root*2],ma[root*2+1]);
}
int ha[200010];
struct Q{
int a,b,c;
}A[200010],B[200010],C[200010];
int cmp1(Q a,Q b){
return a.a<b.a;
}
int cmp2(Q a,Q b){
return a.b<b.b;
}
int main(){
int i,n,m,p;
cin>>n>>m>>p;
for(i=1;i<=n;i++) scanf("%d%d",&A[i].a,&A[i].b);
for(i=1;i<=m;i++) scanf("%d%d",&B[i].a,&B[i].b);
for(i=1;i<=p;i++) scanf("%d%d%d",&C[i].a,&C[i].b,&C[i].c);
sort(A+1,A+1+n,cmp1);
sort(B+1,B+1+m,cmp1);
sort(C+1,C+1+p,cmp2);
for(i=1;i<=n;i++){
update(1,1,n,i,i,-A[i].b);
ha[i]=A[i].a;
}
int k=1,a;
ll ans=-1e18;
for(i=1;i<=m;i++){
while(k<=p&&C[k].b<B[i].a){
a=upper_bound(ha+1,ha+1+n,C[k].a)-ha;
if(a<=n) update(1,1,n,a,n,C[k].c);
k++;
}
ans=max(ans,ma[1]-B[i].b);
}
cout<<ans<<endl;
}
D. Reachable Strings
题意:给一个长度为 n <= 2e5 的01串S,每次可将任意子串011变成110 或者将110变成011。q <=2e5 次询问,每次询问S的两个子串 ,即S [l1...r1] 能否通过任意次变换变成 S[l2..r2]。
题解:对于每次变换,可以发现都是将一个0往左或往右移动两位且之间为两个1,将这两个串中的0都尽量往某方向(左或右) 移动,如果移动之后两串长得一样,则这两原串间可相互变换。(如果两个串不能相互转化,那么把所有0都移向某方向后显然是不一样的)。而一个0每次都是和 相邻的 11 交换位置,所以移动前后,相邻两个0之间1的个数奇偶不变,将每个0的权值设为与前一个0之间1个数的奇偶,那么即可通过hash值来判断这两串向某方移动后是否一样了。最后注意下每个子串中第一个0的权值。。。
。。。还有就是如果 hash 用 二进制 + unsigned long long自然溢出的话会WA10......改为其它进制即可。。
#include<bits/stdc++.h>
using namespace std;
char s[200010];
typedef unsigned long long ull;
int A[200010],B[200010],sum[200010],cnt;
ull p[200010],ha[200010];
ull f(int l,int r){
int len=r-l+1;
return ha[r]-ha[l-1]*p[len];
}
ull ff(int a,int b){
int l=lower_bound(A+1,A+1+cnt,a)-A,r=upper_bound(A+1,A+1+cnt,b)-A-1;
ull val,x;
if(l<=r){
x=(A[l]-a)%2;
val=x*p[r-l];
if(l<r) val+=f(l+1,r);
return val;
}
return 0;
}
int main(){
int i,n,m,num=0,l1,l2,len,r1,r2;
p[0]=1;
for(i=1;i<=200005;i++) p[i]=p[i-1]*5;
scanf("%d",&n);
scanf("%s",s+1);
for(i=1;s[i];i++){
sum[i]=sum[i-1];
if(s[i]=='1') num++;
else{
B[++cnt]=num%2;
num=0;
A[cnt]=i;
sum[i]++;
}
}
for(i=1;i<=cnt;i++) ha[i]=ha[i-1]*5+B[i];
scanf("%d",&m);
while(m--){
scanf("%d%d%d",&l1,&l2,&len);
r1=l1+len-1;
r2=l2+len-1;
if(sum[r1]-sum[l1-1]==sum[r2]-sum[l2-1]&&ff(l1,r1)==ff(l2,r2)) printf("Yes\n");
else printf("No\n");
}
return 0;
}