1. 程式人生 > >【洛谷P1198】最大數

【洛谷P1198】最大數

string lin long logs main scan == i++ lld

這個題最大的難點在於插入,實際上我們可以假設這是一棵早就建好的線段樹,插入只是單點賦值而已

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
typedef long long lo;
lo m,d,t,tail,x;
char s;
struct in
{
    lo l,r,mx;
}ter[800080];
inline void build(lo l,lo r,lo w)//我們可以把它看做這是一棵有m個點的線段樹,那麽只要支持單點修改和區間查詢即可 
{ ter[w].l=l,ter[w].r=r,ter[w].mx=0; if(l==r) return; lo mid=l+r>>1; build(l,mid,w<<1),build(mid+1,r,w<<1|1); } inline void up(lo w) { ter[w].mx=max(ter[w<<1].mx,ter[w<<1|1].mx); } void add(lo l,lo z,lo n,lo w) { if(ter[w].l==ter[w].r&&ter[w].l==l) { ter[w].mx
=(z+n)%d;return;//單點賦值 } lo mid=ter[w].l+ter[w].r>>1; if(l<=mid) add(l,z,n,w<<1); else add(l,z,n,w<<1|1); up(w); } lo ask(lo l,lo r,lo w) { if(ter[w].l==l&&ter[w].r==r) return ter[w].mx; lo mid=ter[w].l+ter[w].r>>1
; if(r<=mid) return ask(l,r,w<<1); else if(l>mid) return ask(l,r,w<<1|1); else return max(ask(l,mid,w<<1),ask(mid+1,r,w<<1|1)); } int main() { scanf("%lld%lld",&m,&d); build(1,m,1); for(int i=1;i<=m;i++) { cin>>s>>x; if(s==A) add(++tail,t,x,1); else { t=ask(tail-x+1,tail,1);printf("%lld\n",t); }//需要記錄下有用的區間右端點和上次所查詢的答案 } }

【洛谷P1198】最大數