码迷,mamicode.com
首页 > 其他好文 > 详细

hud-5475 An easy problem(线段树)

时间:2015-11-20 23:14:02      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:

http://acm.hdu.edu.cn/showproblem.php?pid=5475

技术分享

题意:

原数开始时是1按顺序给你Q个操作,然后其中操作分两种。

1表示将上个操作后的数乘以后面给你的数然后对取余,然后输出结果,2表示除的操作,将现在的数除以指定的先前你所乘上的第几个数

然后对M取模。

思路:

这题用线段树写,断点更新,复杂度是n*(log(n));

代码:

  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<string.h>
  5 #include<stdlib.h>
  6 typedef long long LL;
  7 void up(LL k,LL l);
  8 void build(LL l,LL r,LL k);
  9 LL que(LL l,LL r,LL k,LL aa,LL dd);
 10 typedef struct pp
 11 {
 12     LL x;
 13     LL y;
 14     LL id;
 15     LL t;
 16 } ss;
 17 typedef struct tree1
 18 {
 19     LL x;
 20     LL y;
 21     LL id;
 22     LL cou;
 23 } sd;
 24 LL M,N;
 25 ss cnt[100005];
 26 int flag[4*100005];
 27 sd tree[4*100005];
 28 using namespace std;
 29 int main(void)
 30 {
 31     LL n,i,j,k,p,q;
 32     scanf("%lld",&n);
 33     for(i=1; i<=n; i++)
 34     {
 35         scanf("%lld %lld",&N,&M);
 36         memset(tree,0,sizeof(tree));
 37         for(j=1; j<=N; j++)
 38         {
 39             scanf("%lld %lld",&cnt[j].x,&cnt[j].y);
 40             cnt[j].id=j;
 41             if(cnt[j].x==1)
 42             {
 43                 cnt[j].t=cnt[j].y;//操作1时所要乘的数。
 44             }
 45             else cnt[j].t=1;//操作2时乘的数等价为1;
 46         }
 47         build(1,N,0);//建树(因为每步操作都有对应的操作,所以将操作2也放入一起操所,等价为所要乘的数为1)
 48         printf("Case #%lld:\n",i);
 49         for(j=1; j<=N; j++)
 50         {
 51             if(cnt[j].x==1)
 52             {
 53                 LL dd=que(1,j,0,1,N);//当1时询问找点
 54                 printf("%lld\n",dd);
 55             }
 56             else if(cnt[j].x==2)
 57             {
 58                 up(flag[cnt[j].y],j);//当2时断点更新
 59                 LL dd=que(1,j,0,1,N);//询问找点
 60                 printf("%lld\n",dd);
 61             }
 62         }
 63     }
 64     return 0;
 65 }
 66 void build(LL l,LL r,LL k)//建树
 67 {
 68     tree[k].x=l;
 69     tree[k].y=r;
 70     if(l==r)
 71     {
 72         tree[k].cou=cnt[l].t%M;
 73         flag[l]=k;
 74         return;
 75     }
 76     else
 77     {
 78         build(l,(l+r)/2,2*k+1);
 79         build((l+r)/2+1,r,2*k+2);
 80         tree[k].cou=(tree[2*k+1].cou*tree[2*k+2].cou)%M;
 81     }
 82 }
 83 void up(LL k,LL l)//断点更新
 84 {
 85     tree[k].cou=1;//要删除的点处就相当于乘
 86     k=(k-1)/2;
 87     while(k>=0)//向上更新到根结点
 88     {
 89         tree[k].cou=(tree[2*k+1].cou*tree[2*k+2].cou)%M;
 90         if(k==0)
 91         {
 92             break;
 93         }
 94         k=(k-1)/2;
 95     }
 96 }
 97 LL que(LL l,LL r,LL k,LL aa,LL dd)//询问
 98 {
 99     if(l>dd||r<aa)
100     {
101         return 1;
102     }
103     else if(l<=aa&&r>=dd)
104     {
105         return tree[k].cou;
106     }
107     else
108     {
109         LL nx=que(l,r,2*k+1,aa,(aa+dd)/2);
110         LL ny=que(l,r,2*k+2,(aa+dd)/2+1,dd);
111         return (nx*ny)%M;
112     }
113 
114 }

 

hud-5475 An easy problem(线段树)

标签:

原文地址:http://www.cnblogs.com/zzuli2sjy/p/4982453.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!