E.Transformation
题意:长度为n的区间,初始值都是0,四种操作:opt,x,y,z
1.把区间[x,y]每个数加上z
2.把区间[x,y]每个数乘上z
3.把区间[x,y]所有数变成z
4.计算区间[x,y]内所有数的z次方和(这一条的1<=z<=3)
所有操作 mod 10007
思路:珂朵莉树吧Ovo
#include<iostream>
#include<cstdio>
#include<cstring>
#include<map>
#include<set>
#include<algorithm>
#include<cmath>
#include<string.h>
#include<queue>
#include<vector>
using namespace std;
typedef long long LL;
#define IT set<node>::iterator
struct node{
int l,r;
mutable LL v;
node(int L,int R=-1,LL V=0):l(L),r(R),v(V){}
bool operator<(const node &o)const{
return l<o.l;
}
};
LL qpow(LL a,LL b,LL mod){//快速幂
LL ans=1;
LL x=a%mod;
while(b){
if(b&1)ans=ans*x%mod;
x=x*x%mod;
b>>=1;
}
return ans;
}
set<node>s;
IT split(int pos){
IT it=s.lower_bound(node(pos));
if(it!=s.end()&&it->l==pos)return it;
--it;
int L=it->l,R=it->r;
LL V=it->v;
s.erase(it);
s.insert(node(L,pos-1,V));
return s.insert(node(pos,R,V)).first;
}
void add(int l,int r,LL val){//给l到r所有数加上val
IT itr=split(r+1),itl=split(l);
for(;itl!=itr;++itl)
itl->v=(itl->v+val)%10007;
}
void muti(int l,int r,LL val){//给l到r所有数乘上val
IT itr=split(r+1),itl=split(l);
for(;itl!=itr;++itl)
itl->v=(itl->v*val)%10007;
}
void assign_val(int l,int r,LL val){//把l到r所有数改为val
IT itr=split(r+1),itl=split(l);
s.erase(itl,itr);
s.insert(node(l,r,val));
}
LL sum(int l,int r,int ex){//询问l到r每个数字的x次方和
IT itr=split(r+1),itl=split(l);
LL res=0;
for(;itl!=itr;++itl)
res=(res+(long long)(itl->r - itl->l+1)*qpow(itl->v,(long long)ex,10007))%10007;
return res;
}
int n,m;
int main(){
while(cin>>n>>m,n!=0||m!=0){
s.clear();
for(int i=1;i<=n+1;i++)s.insert(node(i,i,0));
int opt,x,y;
long long z;
for(int i=1;i<=m;i++){
scanf("%d%d%d%lld",&opt,&x,&y,&z);
if(opt==1)add(x,y,z);else
if(opt==2)muti(x,y,z);else
if(opt==3)assign_val(x,y,z);else
printf("%lld\n",sum(x,y,z));
}
}
return 0;
}
I*Travel
K*Best Cow Fences
M.Fight Against Monsters
题意:现在有 n 只怪兽,每只怪兽有一个体力值 HPi 和一个攻击值 ATKi。英雄需要同时和这 n 只怪兽进行战斗。
在每一秒,首先英雄会被当前未被打倒的所有怪兽攻击,受到与这些怪兽的攻击值之和等量的伤害。然后他要选择一只未被打倒的怪兽进行攻击。对同一只怪物进行的第 i 次攻击能对其造成 i 点伤害。
当怪兽的体力值 ≤ 0 的时候就会倒下,当所有怪兽都被打倒时战斗立即结束。
英雄需要合理地进行攻击以使战斗过程中受到的伤害之和最小,请你求出这个最小伤害总量。
思路:贪心。做法与Protecting the flowers完全一样
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<map>
#include<algorithm>
#include<queue>
#include<math.h>
#include<vector>
#include<cstring>
using namespace std;
#define Inf 0x7fffffff
typedef long long ll;
const int N=1000007;
int t,n;
struct node{
ll k,at,hp;
bool operator< (const node &o)const{
return (double)k/at<=(double)o.k/o.at;
}
}a[N];
ll all,ans;
int main(){
cin>>t;
for(int j=1;j<=t;j++){
cin>>n;
ans=all=0;
for(int i=1;i<=n;i++){
scanf("%lld%lld",&a[i].hp,&a[i].at);
a[i].hp*=2;
a[i].k=sqrt(a[i].hp);
if(a[i].k*(a[i].k+1)<a[i].hp)a[i].k++;
all+=a[i].at;
}
sort(a+1,a+1+n);
for(int i=1;i<=n;i++){
ans+=all*a[i].k;
all-=a[i].at;
}
printf("Case #%d: %lld\n",j,ans);
}
}