题目描述
最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分。超级计算机中的任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第Ei秒后结束(第Si秒和Ei秒任务也在运行),其优先级为Pi。同一时间可能有多个任务同时执行,它们的优先级可能相同,也可能不同。调度系统会经常向查询系统询问,第Xi秒正在运行的任务中,优先级最小的Ki个任务(即将任务按照优先级从小到大排序后取前Ki个)的优先级之和是多少。特别的,如果Ki大于第Xi秒正在运行的任务总数,则直接回答第Xi秒正在运行的任务优先级之和。上述所有参数均为整数,时间的范围在1到n之间(包含1和n)。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
吐血,主席树有一个细节没想到。
(这是我见过的第一道卡正解不卡暴力的题。)
正解:
#include<cstdio> #include<algorithm> using namespace std; #define N 300050 #define ll long long inline ll rd() { ll f=1,c=0;char ch = getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){c=10*c+ch-'0';ch=getchar();} return f*c; } ll m,n,cnt; struct ND { ll x,d,fh; }p[2*N]; bool cmp(ND a,ND b) { return a.x<b.x; } ll rt[3*N],tot; struct presgt { ll ls,rs,num,v; }tr[40*N]; void update(ll u) { tr[u].v = tr[tr[u].ls].v+tr[tr[u].rs].v; tr[u].num = tr[tr[u].ls].num+tr[tr[u].rs].num; } void insert(ll l,ll r,ll &u,ll k,ll qx,ll d) { u=++tot,tr[u]=tr[k]; if(l==r) { tr[u].num+=d; tr[u].v+=qx*d; return ; } ll mid = (l+r)>>1; if(qx<=mid)insert(l,mid,tr[u].ls,tr[k].ls,qx,d); else insert(mid+1,r,tr[u].rs,tr[k].rs,qx,d); update(u); } ll query(ll l,ll r,ll u,ll k) { if(!k)return 0; if(l==r) { return tr[u].v/tr[u].num*k;//////////////////!!! } if(tr[u].num<=k)return tr[u].v; int t = tr[tr[u].ls].num; int mid = (l+r)>>1; if(t>=k)return query(l,mid,tr[u].ls,k); else return query(mid+1,r,tr[u].rs,k-t)+tr[tr[u].ls].v; } ll rot[N],mx; int main() { m=rd(),n=rd(); for(ll u,v,d,i=1;i<=m;i++) { u = rd(),v= rd(),d = rd(); p[++cnt].x = u,p[cnt].d = d,p[cnt].fh=1; p[++cnt].x=v+1,p[cnt].d = d,p[cnt].fh=-1; mx = max(mx,d); } sort(p+1,p+1+cnt,cmp); ll now = 1; for(int i=1;i<=n;i++) { while(p[now].x==i) { insert(1,mx,rt[now],rt[now-1],p[now].d,p[now].fh); now++; } rot[i]=rt[now-1]; } ll ans = 1, x, k; for(int i=1;i<=n;i++) { x = rd() , k = 1ll + (rd()*ans+rd())%rd(); ans = query(1,mx,rot[x],k); printf("%lld ",ans); } return 0; }
暴力:
#include<cstdio> #include<algorithm> using namespace std; #define N 100005 #define ll long long ll m,n; struct ND { ll l,r,x; }p[N]; bool cmp(ND a,ND b) { return a.x<b.x; } int main() { scanf("%lld%lld",&m,&n); for(int i=1;i<=m;i++) { scanf("%lld%lld%lld",&p[i].l,&p[i].r,&p[i].x); if(p[i].l>p[i].r) { ll t = p[i].l; p[i].l = p[i].r; p[i].r = t; } } sort(p+1,p+1+m,cmp); ll pre = 1; ll x,a,b,c; for(int i=1;i<=n;i++) { scanf("%lld%lld%lld%lld",&x,&a,&b,&c); a = (a*pre+b)%c+1; pre = 0; ll cnt = 0; for(int j=1;j<=m&&cnt<a;j++) { if(p[j].l<=x&&p[j].r>=x)cnt++,pre+=p[j].x; } printf("%lld ",pre); } return 0; }