您的位置:首页 > 其它

bzoj 3932(主席树)

2016-06-26 21:18 225 查看

3932: [CQOI2015]任务查询系统

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 1452  Solved: 529

[Submit][Status][Discuss]

Description

最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分。超级计算机中的
任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第Ei秒后结束(第Si秒和Ei秒任务也在运行
),其优先级为Pi。同一时间可能有多个任务同时执行,它们的优先级可能相同,也可能不同。调度系统会经常向
查询系统询问,第Xi秒正在运行的任务中,优先级最小的Ki个任务(即将任务按照优先级从小到大排序后取前Ki个
)的优先级之和是多少。特别的,如果Ki大于第Xi秒正在运行的任务总数,则直接回答第Xi秒正在运行的任务优先
级之和。上述所有参数均为整数,时间的范围在1到n之间(包含1和n)。

Input

输入文件第一行包含两个空格分开的正整数m和n,分别表示任务总数和时间范围。接下来m行,每行包含三个空格
分开的正整数Si、Ei和Pi(Si≤Ei),描述一个任务。接下来n行,每行包含四个空格分开的整数Xi、Ai、Bi和Ci,
描述一次查询。查询的参数Ki需要由公式 Ki=1+(Ai*Pre+Bi) mod Ci计算得到。其中Pre表示上一次查询的结果,
对于第一次查询,Pre=1。

Output

输出共n行,每行一个整数,表示查询结果。

Sample Input

4 3

1 2 6

2 3 3

1 3 2

3 3 4

3 1 3 2

1 1 3 4

2 2 4 3

Sample Output

2

8

11

HINT

样例解释

K1 = (1*1+3)%2+1 = 1

K2 = (1*2+3)%4+1 = 2

K3 = (2*8+4)%3+1 = 3

对于100%的数据,1≤m,n,Si,Ei,Ci≤100000,0≤Ai,Bi≤100000,1≤Pi≤10000000,Xi为1到n的一个排列

解题思路:模板题,但是wa了无数次

#include<cstdio>

#include<cstring>

#include<algorithm>

#include<iostream>

#define ll long long 

using namespace std;

int n,m,len,gen,cnt,tail,tail1;

ll sum[18700000],ans,Pre;

int l[18700000],r[18700000],val[18700000],root[110000];

int s[110000],e[110000],p[110000];

int to[210000],next[210000],h[210000];

int go[210000],con[210000],hg[210000],poo[110000];

int x[210000],y[210000];

struct ss

 {

    int zhi,dui;

 }q[110000];

 

inline ll read()

{

    char y; ll x=0,f=1; y=getchar();

    while (y<'0' || y>'9') {if (y=='-') f=-1; y=getchar();}

    while (y>='0' && y<='9') {x=x*10+int(y)-48; y=getchar();}

    return x*f;

}

 

void insert(int x,int y)

 {

    ++len; to[len]=y; next[len]=h[x]; h[x]=len;

 }

  

void insert1(int x,int y)

 {

    ++gen; go[gen]=y; con[gen]=hg[x]; hg[x]=gen; 

 }

 

 

void build(int rot,int &now,int dui,int lo,int ro,int xl,int xr,int yl,int yr)

 {

    if (now==0) now=++cnt,sum[now]=sum[dui],val[now]=val[dui];

    for (int i=xl;i<=xr;++i) ++val[now],sum[now]+=poo[x[i]];

    for (int i=yl;i<=yr;++i) --val[now],sum[now]-=poo[y[i]];

    if (lo==ro) return;

    int mid=(lo+ro)/2;

    if (x[xl]>mid && y[yl]>mid || x[xr]<=mid && y[yr]<=mid)
{
  if (x[xl]>mid && y[yl]>mid)
   {
     l[now]=l[dui]; 
     build(rot,r[now],r[dui],mid+1,ro,xl,xr,yl,yr);
}else
{
r[now]=r[dui];
build(rot,l[now],l[dui],lo,mid,xl,xr,yl,yr);
}
}else
{
   int u1=xl; int u2=yl;
while (x[u1]<=mid && u1<=xr)++u1; --u1;
while (y[u2]<=mid && u2<=yr)++u2; --u2;
build(rot,l[now],l[dui],lo,mid,xl,u1,yl,u2);
   ++u1; ++u2;
build(rot,r[now],r[dui],mid+1,ro,u1,xr,u2,yr);
}

 }

 

void query(int now,int size,int lo,int ro)

 {

    int mid=(lo+ro)/2;

    if (lo==ro)

     {

        ans+=(long long) (size)*poo[lo];

        return;

      }

    if (size==0) return;

    if (val[l[now]]<=size) 

     {

        ans+=sum[l[now]];

        query(r[now],size-val[l[now]],mid+1,ro);

      }else

       {

        query(l[now],size,lo,mid);

       }

 }

 

bool cmp(ss x,ss y)

 {

    return x.zhi<y.zhi;

 }

 

int main()

{
freopen("main.in","r",stdin);
freopen("main.out","w",stdout);

    cnt=0;

    m=read(); n=read(); 

    for (int i=1;i<=m;++i)

     {

        s[i]=read(); e[i]=read(); p[i]=read();

        q[i].zhi=p[i]; q[i].dui=i; 

     }

    sort(q+1,q+m+1,cmp);

    int sug=0; 

    for (int i=1;i<=m;++i)

     {

        if (q[i].zhi!=q[i-1].zhi) ++sug; 

        poo[sug]=p[q[i].dui]; p[q[i].dui]=sug;

     }

    for (int i=1;i<=m;++i)

    {

        insert(s[i],p[i]); insert1(e[i]+1,p[i]);

    }

    for (int i=1;i<=n;++i)

     {

       int u=h[i]; tail=0; tail1=0;

       while (u!=0)

        {

          ++tail; x[tail]=to[u];

          u=next[u];

        }

       u=hg[i];

       while (u!=0)

        {

          ++tail1; y[tail1]=go[u]; 

          u=con[u]; 

        }

       sort(x+1,x+tail+1); sort(y+1,y+tail1+1);

       build(i,root[i],root[i-1],1,n,1,tail,1,tail1);

     }

    Pre=1;

    for (int i=1;i<=n;++i)

     {

        int xi,ai,bi,ci;

        xi=read(); ai=read(); bi=read(); ci=read();

        long long kg=1+(ai*Pre+bi)%ci;

        if (val[root[xi]]<kg) 

         {

            printf("%lld\n",sum[root[xi]]);

            Pre=sum[root[xi]];

          }else

            {

              ans=0;

              query(root[xi],kg,1,m);

              printf("%lld\n",ans);

              Pre=ans;  

            }

     }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: