zoukankan      html  css  js  c++  java
  • 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@
  • 相关阅读:
    Android游戏开发实践(1)之NDK与JNI开发02
    SDK接入(1)之Android Facebook SDK接入
    Markdown学习
    SDK接入(3)之iOS内支付(InApp Purchase)接入
    将列【1,2,3】转换为【类别1,类别2,类别3】
    SQL Server 获取日期
    SQL Server 2000 Split方法
    java连接SqlServer2012
    前辈的js学习方法
    js学习笔记
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/4982453.html
Copyright © 2011-2022 走看看