hud-5475 An easy problem(线段树)

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

An easy problem

Time Limit: 8000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1146    Accepted Submission(s): 560


Problem Description
One day, a useless calculator was being built by Kuros. Let's assume that number X is showed on the screen of calculator. At first, X = 1. This calculator only supports two types of operation.
1. multiply X with a number.
2. divide X with a number which was multiplied before.
After each operation, please output the number X modulo M.
 
Input
The first line is an integer T(1T10), indicating the number of test cases.
For each test case, the first line are two integers Q and M. Q is the number of operations and M is described above. (1Q105,1M109)
The next Q lines, each line starts with an integer x indicating the type of operation.
if x is 1, an integer y is given, indicating the number to multiply. (0<y109)
if x is 2, an integer n is given. The calculator will divide the number which is multiplied in the nth operation. (the nth operation must be a type 1 operation.)

It's guaranteed that in type 2 operation, there won't be two same n.
 
Output
For each test case, the first line, please output "Case #x:" and x is the id of the test cases starting from 1.
Then Q lines follow, each line please output an answer showed by the calculator.
 
Sample Input
1 10 1000000000 1 2 2 1 1 2 1 10 2 3 2 4 1 6 1 7 1 12 2 7
 
Sample Output
Case #1: 2 1 2 20 10 1 6 42 504 84
 
Source
 
Recommend
hujie
 

题意:

原数开始时是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:
",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
",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
",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 }
油!油!you@
原文地址:https://www.cnblogs.com/zzuli2sjy/p/4982453.html