SDNU2020寒假训练赛2题解+补题

题目链接

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);
	}
}
发布了17 篇原创文章 · 获赞 7 · 访问量 2069

猜你喜欢

转载自blog.csdn.net/qq_45530271/article/details/104081231