不可能數據結構(線段樹+思維+找規律)
阿新 • • 發佈:2018-03-03
val import output AD bcg fyi r++ div uwp
我們當然可以直接推,但是既然在電腦上不如直接取一個數操作(這裏取4362349),我們發現$$4362349→83999→35999→23999→11999→3999→3999…$$
所以對於一開始的change操作,我們一直進行到對一個單獨的數操作,只要它變為3999,我們就打下tag,於是就可以愉快的用線段數解決了
不可能數據結構
Description
造一道數據結構題是一件很累的事情。
即使是有了堅固的數據結構造題程式,出題人仍然不能夠一勞永逸。
問題大概出在,造題程式並不總能生成對的題。
比如,造題程式無意產生了一道出題人認為不可做題,這便成了一道錯題。
嘛,出了錯題,其實也是沒有關系的。出題人可以拿著暴力程序跑一個星期來跑出所需要的測試數據。
一個星期跑不出來就延期一個星期機考好了,至於算法和講題嘛,也就看看現場ac代碼現學現賣咯?
可能對你們來說很不幸的現實是,這道題似乎是個錯題。
給你一個初始n個元素的序列,有兩種操作
- 將區間裏的每一個數寫成十進制$(a_1a_2a_3?a_k)_{10}$,然後把這個數變成$\prod ^{k}_{i=1}(a_i+1)−1$
- 詢問一個區間裏面所有數的和。
於是,你能想盡辦法,通過這道不可能數據結構題嗎?
Input
第一行是一個數n,表示這個序列的長度
接下來一行有n個數,描述這個數列。
接下來是一個數q.描述事件個數
對於之後的q行,每行描述一個事件。
- 0 x y,將[x,y]裏面的每一個數做上述變形。
- 1 x y,詢問[x,y]裏面所有數的和。
Output
對於每一個詢問操作,輸出對應的答案。
Hint
看題意數據結構應會使用線段樹,但問題是變化操作並不好執行.
規律大法好
一個經驗之談就是遇到題中有自定義運算的時候,找規律永遠都是一個不錯的選擇
我們考慮什麽數做完改變後仍是自身,即$$A=(a_1a_2a_3?a_k)_{10},\prod ^{k}_{i=1}(a_i+1)−1=A$$
所以對於一開始的change操作,我們一直進行到對一個單獨的數操作,只要它變為3999,我們就打下tag,於是就可以愉快的用線段數解決了
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
#define siz 100010
typedef long long LL;
using namespace std;
template <class T>
void read(T &re) {
re=0;
char c=getchar();
while(c<‘0‘||c>‘9‘) c=getchar();
while(c>=‘0‘&&c<=‘9‘) re=(re<<1)+(re<<3)+(c-‘0‘),c=getchar();
}
int n,m,opt,x,y;
LL ans;
LL a[siz];
struct Node {
int l,r;
LL data;
bool tag;
}node[siz*4];
inline LL trans(LL res) {
LL re=1;
while(res) {
re*=((res%10)+1);
res/=10;
}
return re-1;
}
void build(int p,int l,int r) {
node[p].l=l,node[p].r=r;
if(l==r) { node[p].data=a[l]; return ;}
int mid=(l+r)>>1;
build(p<<1,l,mid),build((p<<1)+1,mid+1,r);
node[p].data=node[p<<1].data+node[(p<<1)+1].data;
}
void find(int p,int l,int r) {
if(node[p].l==l&&node[p].r==r) { ans+=node[p].data; return; }
int mid=(node[p].l+node[p].r)>>1;
if(r<=mid) find(p<<1,l,r);
else if(l>mid) find((p<<1)+1,l,r);
else find(p<<1,l,mid),find((p<<1)+1,mid+1,r);
}
void chan(int p,int l,int r) {
if(node[p].tag) return ;
if(node[p].l==node[p].r) { node[p].data=trans(node[p].data); if(node[p].data==3999) node[p].tag=1; return ;}
int mid=(node[p].l+node[p].r)>>1;
if(r<=mid) chan(p<<1,l,r);
else if(l>mid) chan((p<<1)+1,l,r);
else chan(p<<1,l,mid),chan((p<<1)+1,mid+1,r);
node[p].data=node[p<<1].data+node[(p<<1)+1].data;
if(node[p<<1].tag&&node[(p<<1)+1].tag) node[p].tag=1;
}
int main() {
read(n);
for(register int i=1;i<=n;++i) read(a[i]);
build(1,1,n);
read(m);
while(m--) {
read(opt);
if(opt) {
read(x),read(y);
ans=0,find(1,x,y);
printf("%lld\n",ans);
} else {
read(x),read(y);
chan(1,x,y);
}
}
return 0;
}
?
不可能數據結構(線段樹+思維+找規律)