1101

240pts 题目比较简单 有AK机会但是我放弃了....
没开longlong 见祖宗.....

A 草地排水
时间限制 : - MS 空间限制 : - KB
评测说明 : 1s,256m
问题描述
【问题描述】 我们都知道,草地排水是一道简单的(usaco)网络流裸题。当然,网络流这么简单的知识点做这道题的各位大爷一定都很会做了。所以这道题和网络流并没有关系。
一场大雨过后,长春很多地势低洼的地方都被积水淹没了,(everlasting)家门口的草坪也不例外。脑小的(everlasting)当然不喜欢水啦,它找到了你去帮他家门口的草坪排水。
(everlasting)家门口的草坪可以近似的看作是一条一维直线。这条直线已经完全被积水淹没,你可以认为对于直线上的任意点,积水的深度都是无穷大的。(everlasting)(n)个自动排水装置,对于每个自动排水装置,都有一个作用范围你可以选择任意多个装置使用,以期望得到最大的作用效果总和。但需要注意的是,任意两个装置的作用范围都不能有丝毫的重叠(即使区间端点重叠也是不被允许的)。若你的方案中存在重叠的作用范围,那萌萌的$everlasting (的家就会)BOOM$的一声炸到天上去!你一定不希望这么糟糕的事情发生吧!

解:
简单(DP)
离散化后定义 (f[j]) 代表以j结尾的最大的值
按照右端点从左到右排序 保证每次讨论的时候前面已经被算过了
这道题不能有选或不选的决策 也就是说j位置一定选了
(f[j]=max(f[k])+v;)
注意到(max(f[k]))是前缀最大值 所以树状数组前缀维护最大值就行了

还有一种单调队列的做法
按照起点从左到右排序
每次看结尾有那些在指定区域内都加上
然后单调队列维护一下就行了
code:

//
#include<bits/stdc++.h>
using namespace std;
#define maxnn 200100
#define ll long long
#define GC getchar()
inline ll R() {
	char t;
	ll x=0;
	t=GC;
	while(!isdigit(t)) {
		t=GC;
	}
	while(isdigit(t)) {
		x=x*10+t-'0';
		t=GC;
	}
	return x;
}
ll f[maxnn];
ll n;
#define lowbit(i) i&(-i)
ll c[maxnn];
void add(ll x,ll d) {
	for(int i=x; i<=n+100100; i+=lowbit(i)) {
		c[i]=max(c[i],d);
	}
}
ll get(ll x) {
	ll ans=0;
	for(int i=x; i; i-=lowbit(i)) {
		ans=max(c[i],ans);
	}
	return ans;
}
struct node {
	ll fir,sec,v;
} a[maxnn];
bool cmp(node a,node b) {
	return a.sec<b.sec;
}
ll d[maxnn],cnt;
int main() {
	//freopen("water.in","r",stdin);
	//freopen("water.out","w",stdout);
	n=R();
	for(int i=1; i<=n; i++) {
		a[i].fir=R();
		a[i].sec=R();
		a[i].v=R();
		d[++cnt]=a[i].fir;
		d[++cnt]=a[i].sec;
	}
	sort(d+1,d+1+cnt);
	ll r=unique(d+1,d+1+cnt)-d;
	for(int i=1; i<=n; i++) {
		a[i].fir=lower_bound(d+1,d+r,a[i].fir)-d;
		a[i].sec=lower_bound(d+1,d+r,a[i].sec)-d;
	}
	sort(a+1,a+1+n,cmp);
	ll ans=0;
	for(int i=1; i<=n; i++) {
		f[a[i].sec]=max(f[a[i].sec],get(a[i].fir-1)+a[i].v);
		add(a[i].sec,f[a[i].sec]);
		ans=max(ans,f[a[i].sec]);
	}
	cout<<ans;
}

B 化学
时间限制 : - MS 空间限制 : - KB
评测说明 : 1s,256m

解:
折半搜索或者分段打表
然后我考试的时候以为对拍了就稳了 然后就没有静态差错更加没有看全数据范围 (m ≤ 10^18) (1 ≤q≤ 10^18)
上次考试也是这样 数据范围没有看 然后就想当然地以为对拍了就没有错 真是失智

看完题目一定要看数据范围 加亮标记 题目要读三遍!!! 最后检查的时候一定要看wan数据范围一定要静态查错....
附上代码:

//
#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define maxnn 60
vector<ll> Q1,Q2;
ll n,m;
ll all1,all2;
ll e1[maxnn],e2[maxnn];
ll p[maxnn];
#define GC getchar()
inline ll R() {
	char t;
	ll x=0;
	t=GC;
	while(!isdigit(t)) {
		t=GC;
	}
	while(isdigit(t)) {
		x=x*10+t-'0';
		t=GC;
	}
	return x;
}
int main()
{
	//freopen("chemistry.in","r",stdin);
	//freopen("chemistry.out","w",stdout);
	n=R();m=R();
	for(int i=1;i<=n;i++)
	{
		p[i]=R();
	}
	ll d1=n/2;
	all1=(1LL<<d1)-1;
	ll d2=n-d1;
	all2=(1LL<<d2)-1;
	for(int i=1;i<=d1;i++)
	{
		e1[i]=p[i];
	}
	ll num=0;
	for(int i=d1+1;i<=n;i++)
	{
		e2[++num]=p[i];
	}
	for(int i=0;i<=all1;i++)
	{
		ll d=0;
		for(int j=1;j<=d1;j++)
		{
			if(i&(1<<j-1))
			{
				d+=e1[j];
			}
		}
		Q1.push_back(d);
	}
		for(int i=0;i<=all2;i++)
	{
		ll d=0;
		for(int j=1;j<=d2;j++)
		{
			if(i&(1<<j-1))
			{
				d+=e2[j];
			}
		}
		Q2.push_back(d);
	}
	sort(Q1.begin(),Q1.end());
	sort(Q2.begin(),Q2.end());
	ll ans=0;
	for(int i=0;i<Q1.size();i++)
	{
		int d=Q2.size();
		d--;
		if(Q2[d]<=(m-Q1[i])) {ans+=d+1;continue;}
		ans+=upper_bound(Q2.begin(),Q2.end(),m-Q1[i])-Q2.begin();
	}
	cout<<ans;
}

C 读书
时间限制 : - MS 空间限制 : - KB
评测说明 : 1s,256m

解:
贪心一下 考虑链就行了
code:

//
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxnn 1000010
int size[maxnn];
int T;
int n;
int f[maxnn][24];
#define GC getchar()
inline ll R() {
	char t;
	ll x=0;
	t=GC;
	while(!isdigit(t)) {
		t=GC;
	}
	while(isdigit(t)) {
		x=x*10+t-'0';
		t=GC;
	}
	return x;
}
int las[maxnn],en[maxnn],le[maxnn],tot,nex[maxnn];
int dep[maxnn];
void add(int a,int b) {
	en[++tot]=b;
	nex[tot]=las[a];
	las[a]=tot;
}
int goup(int x,int k) {
	int s=log2(n);
	for(int i=s; i>=0; i--) {
		if((1<<i)&k) {
			x=f[x][i];
		}
	}
	return x;
}
void dfs1(int v,int fa) {
	dep[v]=dep[fa]+1;
	f[v][0]=fa;
	size[v]=1;
	int s=log2(n);
	for(int i=1; i<=s; i++) {
		f[v][i]=f[f[v][i-1]][i-1];
	}
	for(int i=las[v]; i; i=nex[i]) {
		int u=en[i];
		if(u!=fa) {
			dfs1(u,v);
			size[v]+=size[u];
		}
	}
}
void clear()
{
	memset(las,0,sizeof(las));
	tot=0;
	memset(size,0,sizeof(size));
	memset(dep,0,sizeof(dep));
	memset(f,0,sizeof(f));
}
void FIE()
{
	freopen("book.in","r",stdin);
	freopen("book.out","w",stdout);
}
int main() {
	//FIE();
	T=R();
	while(T--) {
		clear();
		n=R();
		int x,y;
		for(int i=1; i<n; i++) {
			x=R();
			y=R();
			add(x,y);
			add(y,x);
		}
		dfs1(1,1);
		int tmp1=0;
		int tmp2=0;
		int d=(dep[n]-dep[1]-1)/2;
		int r=goup(n,d);
		tmp2=size[r];
		tmp1=n-size[r];
		puts(tmp1>tmp2?"^_^":"T_T");
	}
}

下次再不看数据范围我就》》》
不要以为对拍就没事 要静态查错注意数据范围

原文地址:https://www.cnblogs.com/OIEREDSION/p/11776229.html