80分求助!!!第二个点和第六个点,考虑过重复情况
查看原帖
80分求助!!!第二个点和第六个点,考虑过重复情况
272314
Autonomier楼主2020/7/12 15:56
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
inline int read(){
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}
int s,e,q,d[maxn];
int rt[maxn];
struct hjt_tree
{
	int l,r;
	int sum;
	long long pri;
}t[maxn*40];
//pri维护当前权值区间的优先级之和
//sum维护当前值域上出现 了几个数 
int cnt;
inline int build(int l,int r)
{
	int num=++cnt;
	if(l!=r)
	{
		int mid=(l+r)>>1;
		t[num].l=build(l,mid);
		t[num].r=build(mid+1,r);
	}
	return num;
}//这里的建树貌似没什么用 
inline void push_up(int now)
{
	t[now].pri=t[t[now].l].pri+t[t[now].r].pri;
}
inline int update(int l,int r,int p,int pre,int fg)
//fg代表当前是要加上(1)这个任务或者删除(-1) 
{
	//cout<<1;
	int num=++cnt;
	t[num]=t[pre];
	t[num].sum+=fg;
	if(l==r)
	{
		t[num].pri=d[l]*t[num].sum;
		return num;
	}
	int mid=(l+r)>>1;
	if(p<=mid)
		t[num].l=update(l,mid,p,t[pre].l,fg);
	else
		t[num].r=update(mid+1,r,p,t[pre].r,fg);
	push_up(num);
	return num; 
}
inline long long query(int l,int r,int k,int now)
{
//	cout<<l<<" "<<r;
	int num=0;
	//以下考虑的是到叶子节点的情况 
	if(l==r&&t[now].sum>=k)
	{
	//	cout<<l<<" "<<r;
		return k*d[l];
	}
	else if(l==r)
	{
		return t[now].pri;
	}
	//常规递归查询 
	int mid=(l+r)>>1;
	if(t[t[now].l].sum==k)
		return t[t[now].l].pri;
	else if(t[t[now].l].sum<k)
		return 	t[t[now].l].pri+query(mid+1,r,k-t[t[now].l].sum,t[now].r);
	else
		return query(1,mid,k,t[now].l);
}
vector<int> st[maxn],en[maxn],o[maxn];
int main()
{
//	freopen("P3168_2.in","r",stdin);
//	freopen("out1.txt","w",stdout);
	int n,m;
	n=read(),m=read();
	int time=0;
	for(int i=1;i<=n;i++)
	{
		s=read(),e=read(),q=read();
		time=max(time,e);
		st[s].push_back(q);
		en[e+1].push_back(q);
		d[i]=q;
	}
	sort(d+1,d+1+n);
	int siz=unique(d+1,d+1+n)-d-1;
	//离散化 
	rt[0]=build(1,siz);
	for(int i=1;i<=time;i++)
	{
		rt[i]=rt[i-1];
		for(int j=0;j<st[i].size();j++)
		{
			int x=lower_bound(d+1,d+1+siz,st[i][j])-d;
			rt[i]=update(1,siz,x,rt[i],1);
		}
		for(int j=0;j<en[i].size();j++)
		{
			int x=lower_bound(d+1,d+1+siz,en[i][j])-d;
			rt[i]=update(1,siz,x,rt[i],-1);
		}	
	}
	long long pre=1;
	for(int i=1;i<=m;i++)
	{
		int a,b,c;
		int x;
		x=read();
		a=read(),b=read(),c=read();
		int k=1+(a*pre+b)%c;
		if(k>=t[rt[x]].sum)//如果k比任务个数还多 
		{
			pre=t[rt[x]].pri;
			printf("%lld\n",pre);
			continue;
		} 
		pre=query(1,siz,k,rt[x]);
		printf("%lld\n",pre);	
	}
	return 0;
}
2020/7/12 15:56
加载中...