hdu4893Wow! Such Sequence! (線段樹),hdu4893wowsequence

來源:互聯網
上載者:User

hdu4893Wow! Such Sequence! (線段樹),hdu4893wowsequence
Problem DescriptionRecently, Doge got a funny birthday present from his new friend, Protein Tiger from St. Beeze College. No, not cactuses. It's a mysterious blackbox.

After some research, Doge found that the box is maintaining a sequence an of n numbers internally, initially all numbers are zero, and there are THREE "operations":

1.Add d to the k-th number of the sequence.
2.Query the sum of ai where l ≤ i ≤ r.
3.Change ai to the nearest Fibonacci number, where l ≤ i ≤ r.
4.Play sound "Chee-rio!", a bit useless.

Let F0 = 1,F1 = 1,Fibonacci number Fn is defined as Fn = Fn - 1 + Fn - 2 for n ≥ 2.

Nearest Fibonacci number of number x means the smallest Fn where |Fn - x| is also smallest.

Doge doesn't believe the machine could respond each request in less than 10ms. Help Doge figure out the reason.
InputInput contains several test cases, please process till EOF.
For each test case, there will be one line containing two integers n, m.
Next m lines, each line indicates a query:

1 k d - "add"
2 l r - "query sum"
3 l r - "change to nearest Fibonacci"

1 ≤ n ≤ 100000, 1 ≤ m ≤ 100000, |d| < 231, all queries will be valid.
OutputFor each Type 2 ("query sum") operation, output one line containing an integer represent the answer of this query.
Sample Input

1 12 1 15 41 1 71 3 173 2 42 1 5

Sample Output
022

Source2014 Multi-University Training Contest 3
Recommendhujie | We have carefully selected several similar problems for you:4896 4895 4894 4892 4891解題:線段樹結點含兩個和,一個真正和,另一個是3號操作的備用和。
#include<iostream>#include<stdio.h>using namespace std;struct tree{    int l,r,t;    __int64 s,ts;}ss[100010*3];__int64 f[100]={1,1};void setit(int l,int r,int d){    ss[d].l=l;    ss[d].r=r;    ss[d].t=0;//判斷子結點是否需要進行3號操作    ss[d].s=0;//當前區間內的總和    ss[d].ts=1;//當前區間進行3號操作的備用和    if(l==r)        return;    setit(l,(l+r)/2,d*2);    setit((l+r)/2+1,r,d*2+1);    ss[d].ts=ss[d*2].ts+ss[d*2+1].ts;}__int64 doublekill(__int64 k)//尋找與k最相近的Fibonacci{    int l=0,r=77,mid;    __int64 x1,x2;    while(l<=r)    {        mid=(l+r)/2;        if(f[mid]==k)return f[mid];        if(f[mid]<k)l=mid+1;        else r=mid-1;    }    x1=f[l]-k;    if(x1<0)x1=-x1;    if(l>0)    {        x2=f[l-1]-k;        if(x2<0)x2=-x2;        if(x2<=x1)return f[l-1];    }    return f[l];}void insert1(__int64 e,int k,int d)//點更新{    int l,r,mid;    l=ss[d].l;    r=ss[d].r;    mid=(l+r)/2;    if(l==r)    {        if(ss[d].t)        {            ss[d].s=ss[d].ts; ss[d].t=0;        }        ss[d].s+=e; ss[d].ts=doublekill(ss[d].s);//同時更新備用        return;    }    if(ss[d].t)//如果當前段需要進行3號操作    {        ss[d*2].t=1; ss[d*2+1].t=1; ss[d].t=0;        ss[d*2].s=ss[d*2].ts;        ss[d*2+1].s=ss[d*2+1].ts;    }    if(k>mid)insert1(e,k,d*2+1);    else insert1(e,k,d*2);    ss[d].s=ss[d*2].s+ss[d*2+1].s;    ss[d].ts=ss[d*2].ts+ss[d*2+1].ts;}void insert2(int l,int r,int d)//區間進行3號操作{    int ll,rr,mid;    ll=ss[d].l;    rr=ss[d].r;    mid=(ll+rr)/2;    if(ll>=l&&rr<=r)    {        ss[d].s=ss[d].ts; ss[d].t=1;//子結點需要3號操作更新        return;    }    if(ss[d].t)    {        ss[d*2].t=1; ss[d*2+1].t=1; ss[d].t=0;        ss[d*2].s=ss[d*2].ts;        ss[d*2+1].s=ss[d*2+1].ts;    }    if(l<=mid)insert2(l,r,d*2);    if(r>mid)insert2(l,r,d*2+1);     ss[d].s=ss[d*2].s+ss[d*2+1].s;}__int64 find(int l,int r,int d)//求和{    __int64 ll,rr,mid,s=0;    ll=ss[d].l;    rr=ss[d].r;    mid=(ll+rr)/2;    if(ll>=l&&rr<=r)    {        return ss[d].s;    }    if(ss[d].t)    {        ss[d*2].t=1; ss[d*2+1].t=1; ss[d].t=0;        ss[d*2].s=ss[d*2].ts;        ss[d*2+1].s=ss[d*2+1].ts;    }    if(l<=mid)s+=find(l,r,d*2);    if(r>mid)s+=find(l,r,d*2+1);    ss[d].s=ss[d*2].s+ss[d*2+1].s;    return s;}int main (void){    int n,m,i,j,k,l;    __int64 d;    for(i=2;i<78;i++)    f[i]=f[i-1]+f[i-2];    while(scanf("%d%d",&n,&m)>0)    {        setit(1,n,1);        while(m--)        {            scanf("%d%d",&j,&k);            if(j==1)            {                scanf("%I64d",&d);insert1(d,k,1);            }            else            {                scanf("%d",&l);                if(j==2)printf("%I64d\n",find(k,l,1));                else insert2(k,l,1);            }        }    }    return 0;}



HDU的acm1199題總是WA,估計數組範圍不夠,這題數組應該開多少?All the input are less than 2^31-1

題目說了,資料範圍到2^31-1。但是顯然我們開不了這麼大的數組……再退一萬步說,就算能開這麼大的數組,用暴力演算法,這個O(2000*2^31)的時間複雜度估計得算一個小時吧……

如果你是acm初學者;或者如果你不想搞acm只是想練一些題提高代碼水平;或者如果你連二叉樹都還寫的不熟練:
請跳過這個題。

如果你有了一定的代碼能力,如果你是要認真的搞acm,這個題就是必會的資料結構之一:線段樹。請百度線段樹的有關知識,一搜一大把。另外,由於這個資料範圍實在太大,會涉及到資料離散化的知識。建議你先找一個不用離散化的普通線段樹的題,過了之後再來搞這個題。

有問題歡迎追問。
 
怎將C++整型數組數字串轉換成對應的十進位整數,如j將 int a[4]=1234轉換成int i=1234,急,拜託了

在庫stdlib.h中提供的函數
int atoi ( const char * str );
Convert string to integer

Parses the C string str interpreting its content as an integral number, which is returned as an int value.

The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value.

The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function.

If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed.
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.