T1 Merchant T2 Equation T3 Rectangle

期望得分:22+100+22=144
实际得分:22+86+22=130

出题人有卡常嫌疑?(自信点,把问号去掉)

开题顺序3 1 2,T3一眼不可做,打上\(O(n^4)\)的暴力

然后T1发现状压可22pts,打上状压

然后觉得T1可做,根据之前的经验,决定先从T3骗点分再回来想T1正解

然后发现T3这个方程有点水,想出正解思路后,由于存在正解码错爆0的案例,就一直手模数据,T1就放下了

比赛结束最后看题解,发现T1竟是最可做的,,,

要给觉得可做的题多留些思考时间,提高效率,心态放平

T1

将n个物品划分为\(O(2^n)\)个集合,每个集合看做是一个一次函数

所有的一次函数的最大值,在坐标系上 单增 或 单减 或 先减后增

对于对于单减和先减后增的减,用0特判

剩下的情况具有单调性,二分就行了

T2

树上的每个点的x值可以转化成\(x_i=x_1+k\)或\(x_i=-x_1+k\) ,与深度有关

回答每次询问时,若两个的\(x_1\)的符号相反,判断\(k_i+k_j\)与\(w\)的关系。

若相同,判个整数,直接解出来

然后若一个节点的\(w\)改变,只对它的子树有影响,维护\(dfs\)序区间修改,单点查询

线段树被卡,用树状数组维护差分数组就行了

T3

正解还不会,\(O(n^4)\)的暴力就枚举每个矩形的上下左右边界的点,然后打标记去个重就22pts了

冥冥中想起一句话,记得取模

代码

T1

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1000011;
struct pot_{
	int k,b;
}pot[N];
int n,m,s;
int ans1[N];
priority_queue<int> dui;
inline int read()
{
	int ss=0,w=1;
	char ch=getchar();
	while(ch>'9'||ch<'0')
	{
		if(ch=='-')
			w=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		ss=(ss<<1)+(ss<<3)+(ch^48);
		ch=getchar();
	}
	return ss*w;
}
bool cmp(int a,int b)
{
	return a>b;
}
bool check(int x)
{
	for(int i=0;i<n;i++)
		ans1[i]=pot[i+1].k*x+pot[i+1].b;
	nth_element(ans1,ans1+m,ans1+n,cmp);
	int ans=0;
	for(int i=0;i<m;i++)
	{
		if(ans1[i]<0)
			continue;
		ans+=ans1[i];
		if(ans>=s)
			return 1;
	}
	return 0;
}
signed main()
{
	int ans2=0;
	n=read();
	m=read();
	s=read();
	for(int i=1;i<=n;i++)
	{
		pot[i].k=read();
		pot[i].b=read();
		dui.push(pot[i].b);
	}
	for(int i=1;i<=m;i++)
	{
		if(dui.top()<0)
			break;
		ans2+=dui.top();
		dui.pop();
	}
	if(ans2>=s)
	{
		cout<<0<<endl;
		return 0;
	}
	int l=1,mid,r=1e9,ans=0x7ffffffffffffff;
	while(l<=r)
	{
		mid=(l+r)>>1;
		if(check(mid))
		{
			ans=mid;
			r=mid-1;
		}
		else
			l=mid+1;
	}
	cout<<ans<<endl;
	return 0;
}

T2

#include<bits/stdc++.h>
using namespace std;
const int N=1000011;
struct qxxx{
	int v,next;
}cc[2*N];
int n,q;
int dep[N],size[N];
int dfn[N],rle[N],st;
int first[N],cnt;
long long w[N],sum[N];
long long cs1[N],cs2[N];
long long cf1[N],cf2[N];
inline int read()
{
	int s=0,w=1;
	char ch=getchar();
	while(ch>'9'||ch<'0')
	{
		if(ch=='-')
			w=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		s=(s<<1)+(s<<3)+(ch^48);
		ch=getchar();
	}
	return s*w;
}
void qxx(int u,int v)
{
	cc[++cnt].v=v;
	cc[cnt].next=first[u];
	first[u]=cnt;
	return;
}
int lowbit(int x)
{
	return x&(-x);
}
void insert1(int x,long long val)
{
	while(x<=n)
	{
		cf1[x]+=val;
		x+=lowbit(x);
	}
	return;
}
void insert2(int x,long long val)
{
	while(x<=n)
	{
		cf2[x]+=val;
		x+=lowbit(x);
	}
	return;
}
long long ask1(int x)
{
	long long sum=0;
	while(x)
	{
		sum+=cf1[x];
		x-=lowbit(x);
	}
	return sum;
}
long long ask2(int x)
{
	long long sum=0;
	while(x)
	{
		sum+=cf2[x];
		x-=lowbit(x);
	}
	return sum;
}
void dfs(int x)
{
	dfn[x]=++st;
	rle[st]=x;
	size[x]=1;
	for(int i=first[x];i;i=cc[i].next)
	{
		dep[cc[i].v]=dep[x]+1;
		sum[cc[i].v]=-sum[x]+w[cc[i].v];
		dfs(cc[i].v);
		if(dep[cc[i].v]&1)
			cs1[dfn[cc[i].v]]=sum[cc[i].v];
		else
			cs2[dfn[cc[i].v]]=sum[cc[i].v];
		size[x]+=size[cc[i].v];
	}
	return;
}
void pre()
{
	for(int i=1;i<=n;i++)
	{
		insert1(i,cs1[i]-cs1[i-1]);
		insert2(i,cs2[i]-cs2[i-1]);
	}
	return;
}
int main()
{
	int jd;
	int x,y,z;
	n=read();
	q=read();
	for(int i=2;i<=n;i++)
	{
		qxx(read(),i);
		w[i]=read();
	}
	dep[1]=1;
	dfs(1);
	pre();
	for(int i=1;i<=q;i++)
	{
		jd=read();
		if(jd==1)
		{
			x=read();
			y=read();
			z=read();
			long long xa,ya;
			long long sgx,sgy;
			if(dep[x]&1)
			{
				sgx=1;
				xa=ask1(dfn[x]);
			}
			else
			{
				sgx=-1;
				xa=ask2(dfn[x]);
			}
			if(dep[y]&1)
			{
				sgy=1;
				ya=ask1(dfn[y]);
			}
			else
			{
				sgy=-1;
				ya=ask2(dfn[y]);
			}
			if(sgx+sgy==0)
			{
				if(xa+ya==z)
					printf("%s\n","inf");
				else
					printf("%s\n","none");
			}
			else
			{
				long long fz=z-xa-ya;
				long long fm=sgx+sgy;
				if(fz%fm)
					printf("%s\n","none");
				else
					printf("%lld\n",fz/fm);
			}
		}
		else
		{
			x=read();
			y=read();
			long long val=y-w[x];
			if(!(dep[x]&1))
				val*=-1;
			insert1(dfn[x],val);
			insert1(dfn[x]+size[x],-val);
			insert2(dfn[x],-val);
			insert2(dfn[x]+size[x],val);
			w[x]=y;
		}
	}
	return 0;
}