您的位置:首页 > 其它

hdu-5475-An easy problem-线段树求乘积

2015-09-26 23:50 288 查看
题意。初始X=1;

给n,mod ,表示n次操作

操作1格式 : 1 b 表示用x乘上b

操作2格式: 2 n 表示 当前x除掉第n次 "1操作” 的数

每次操作输出一个答案,输出的答案是要对mod取模

由于有除法所以我们不能每一步取模

一直在想什么办法能过。。。最后卡死了。。

赛后才知道 直接就是一个长度为n的rmq线段树

每个点维护一个数 初始值为1

操作1 就是 修改第i个数为b;

操作2 就是把第对应的数改为1就好了

每次查询 直接查询

对 每次2操作,都要找到长度为1的该区间 修改值为1 然后往上递归修改

所维护的区间里, 长度为1 的区间 也就是画成二叉树后 最底层的区间(仅仅记录一个数) 是不能取模的

其余区间 都可以储存取模后的值(不取模也存不下....)

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <queue>
#include <set>
#include <vector>
#define  inf 0x7fffffff
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const __int64 maxn = 100005;
__int64 mod;
__int64 st_min[maxn<<4] ;
__int64 aa[maxn];
inline __int64 minn(__int64 a,__int64 b) { return a>b?b:a; }
inline __int64 maxx(__int64 a,__int64 b) { return a>b?a:b; }
void PushUP_del(__int64 rt)
{
	 st_min[rt] = (st_min[rt<<1]*st_min[rt<<1|1])%mod;
}
void PushUP(__int64 rt,__int64 val)
{
    st_min[rt] = (st_min[rt<<1]*st_min[rt<<1|1])%mod;
}
__int64  ok=0;
void build(__int64 l,__int64 r,__int64 rt) {
    if (l == r)
    {     st_min[rt]=1;         
        return ;
    }
    __int64 m = (l + r) >> 1;
    build(lson);
    build(rson);
   st_min[rt]=1; 
}

 
void del(__int64 l,__int64 r,__int64 rt,__int64 num,__int64 val) 
{
    if (l == r&& l==num)
    {    
        st_min[rt]/=val; 
        return ;
    }
    __int64 m = (l + r) >> 1;
    if (num<=m)
    del(lson,num,val);
    else
    del(rson,num,val);
    
    PushUP_del(rt);
}

void update(__int64 l,__int64 r,__int64 rt,__int64 num,__int64 val) 
{
    if (l == r&& l==num)
    {    
        st_min[rt]*=val;  
        return ;
    }
    __int64 m = (l + r) >> 1;
    if (num<=m)
    update(lson,num,val);
    else
    update(rson,num,val);
    
    PushUP(rt,val);
}
 

__int64 query (__int64 qL,__int64 qR,__int64 l,__int64 r,__int64 rt) //rt是节点编号
{
    if (qL <= l && r <= qR) {
        return st_min[rt]%mod;
    }
    __int64 m = (l + r) >> 1;
    __int64 ret1 = 1,ret2 = 1;
    if (qL <= m) ret1 = query(qL , qR , lson);    //复杂情况可直接R<=m作return条件 省时
    if (qR > m) ret2 = query(qL , qR , rson);
    return (ret1*ret2)%mod;
} 
 
__int64 op_num[100005];
int main()
{
    __int64 n ,a,b,i;
    __int64 t;
    scanf("%I64d",&t);
	int cnt=1;
  while(t--)
    {
      scanf("%I64d%I64d",&n,&mod); 
      __int64 ok=0;
    //    memset(sum,0,sizeof(sum));
     
	  printf("Case #%d:\n",cnt++);
    build(1,n,1);
 

        for(  i = 1; i <= n; i++)
        {
            scanf("%I64d %I64d",&a,&b); 
            op_num[++ok]=b;
            if (a==1)
                update(1,n,1,i,b); 
            else
            { 
                del(1,n,1,b,op_num[b]); 
            }
    
            printf("%I64d\n",query(1,i,1,n,1) );
     
        }
             
        
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: