Problem B: 2048
Special Judge
Time Limit: 1000 ms Memory Limit: 256 MB
Description
2048 was once a popular global game.
Today, we have a different way to play this game.
Now, you have a double-ended queue, you can only elements from the left or from the right into the double-ended queue. Once placed shall not be removed. After placed, if there are two consecutive identical elements in the queue, they are automatically merged into a new element - the original and the two elements. If the same new element to its adjacent elements, continued consolidation ......
Such as: deque have 2, 4, 16 three elements. If 2 is inserted from the left end deque, the queue becomes 8, 16. If 2 is inserted from the right end of the deque, the queue will become 2, 4, 16, 2.
Beginning, deque is empty. We'll give you some numbers, you need to turn inserted into the double-ended queue. Asked if there is a program of operation, such that the deque last only a few.
Input
A first line integer T, denotes the number of data sets.
For each set of test data:
The first line an integer n, the number represents the number we give you.
The next line number n, mean that we give you the number ai. These numbers are non-negative integer power of 2, i.e., for each i there is an integer k satisfies k≥0 and ai = 2 ^ k.
Output
For each set of data, so that if there is a program operating deque last only a few, output no. Otherwise, the output of a string of length n, wherein if the i-th inserted from left to deque, the i-th character is L; if the i-th inserted from right to deque, the i-th characters r.
Sample Input
3
9
2 8 4 1 1 4 4 4 4
5
2 16 4 8 2
3
2 2 2
Sample Output
rrrlllrrr
no
no
HINT
Sample 1 explanation
1, 2 is inserted from the right side, it becomes deque 2
2, is inserted from the right 8, 28 becomes the deque
3, 4 is inserted from the right side, the deque to become 284
4, inserted from the left one, becomes the deque 1284
5, 1 is inserted from the left, the deque to become 484
6, 4 is inserted from the left, the deque to become 164
7, 4 is inserted from the right side, the deque to become 168
8, inserted from the right 4, the deque to become 1684
9, 4 is inserted from the right side, it becomes deque 32
Data range and Conventions
For 20% of the data, n≤19, T≤100
For all data, 1≤n≤1000, a1 ~ an, and no more than 2 ^ 13, T≤10000, wherein the data n> 20 is not more than 150 groups.
Solution
Consider pressure-like search +
L represents a click with the left half of the current state, then the right half of the prefix can be represented by L and subtracting pretreated
If you want to join the current number smaller than L, lowbit, then left to join
Similarly the right part
Then a vis said about the current state has not been searched. Since the maximum is only 8192, so the array is in bloom.
For L and R of a state, if highbit (L) <= highbit (R), then put highbit (R) combined to the left, so that the right and left merged completed
Fine I understand (though I speak unclear)
#include<bits/stdc++.h>
using namespace std;
#define R (sum[x]-L)
#define lowbit(x) x&-x
int n;
int a[10001];
bool flag;
int vis[1010][8195];
bool ans[10001];
int sum[10001];
int highbit[10001];
int sb;
void solve(int x,int L){
//cout<<x<<" "<<L<<endl;
if(highbit[L]<=highbit[R])L+=highbit[R];
if(vis[x][L]==sb)return;
vis[x][L]=sb;
if(x==n){
//cout<<L<<" "<<(lowbit(L))<<endl;
if(L==(lowbit(L)))flag=true;
return;
}
int xx=x+1;
int l=(lowbit(L)),r=(lowbit(R));
if(a[xx]<=l)ans[xx]=0,solve(xx,L+a[xx]);
if(flag)return;
if(!r||a[xx]<=r)ans[xx]=1,solve(xx,L);
}
void init(){
for(int i=2;i<=8192;++i)highbit[i]=highbit[i>>1]+1;
for(int i=1;i<=8192;++i)highbit[i]=1<<highbit[i];
}
void print(){
for(int i=1;i<=n;++i){
putchar((ans[i]?'r':'l'));
}
putchar('\n');
}
int main(){
int T;
scanf("%d",&T);
//T=1;
init();
while(T--){
memset(sum,0,sizeof(sum));
memset(ans,0,sizeof(ans));
flag=false;
sb++;
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
sum[i]=sum[i-1]+a[i];
}
//cout<<sum[n]<<endl;
if(sum[n]!=(lowbit(sum[n]))){
puts("no");
continue;
}
solve(1,a[1]);
if(flag){
print();
}
else puts("no");
}
}
Problem C: Subsequence Count
Time Limit: 1000 ms Memory Limit: 256 MB
Description
Given a string S1 ⋯ n 01 and Q operations.
There are two types of operations:
1, the number of [l, r] negated interval (therein becomes 0 becomes 0 1,1).
2, the query string S substring Sl ⋯ r the number of different sequences. Since the answer may be large, please answer of 10 ^ 9 + 7 modulo.
In mathematics, the subsequence is a sequence from the initial relative position of the sequence without destroying the elements by removing some of the remaining elements (preceding or following) formed by the new sequence.
Input
The first line contains two integers N and Q, respectively, and a string length number of operations.
The second line contains a string S.
Next Q lines of type integer of 3, l, r, wherein the type represents the type of operation, l, r represents the operation interval [l, r].
Output
For each inquiry type = 2, the output of a integer answer. Since the answer may be large, please answer of 10 ^ 9 + 7 modulo.
Sample Input
4 4
1010
2 1 4
2 2 4
1 2 3
2 1 4
Sample Output
11
6
8
HINT
For 5% of data, N≤20, Q = 1
For 10% of the data, N≤1000, Q = 1
For 20% of the data, N≤10 ^ 5, Q≤10
For another 30% of the data, 1≤N≤10 ^ 5,1≤Q≤10 ^ 5, type = 2
To 100% of the data, 1≤N≤105,1≤Q≤105
Solution
We use the number string Qiuzi dp, dp set [i] [0/1], representative of the i-th bit dp, the number of a few to the end of the substring 0/1
Have
\(dp[i][s[i]]=dp[i-1][s[i]]+dp[i-1][!s[i]]+1,dp[i][!s[i]]=dp[i-1][!s[i]]\)
Then turn in a matrix:
\[ if(s[i]==0)\left[ \begin{matrix} 1 & 0 & 0 \\ 1 & 1 & 0 \\ dp[i][0] & dp[i][1] & 1 \\ \end{matrix} \right] \]
\[ if(s[i]==1)\left[ \begin{matrix} 1 & 1 & 0 \\ 0 & 1 & 0 \\ dp[i][0] & dp[i][1] & 1 \\ \end{matrix} \right] \]
Then each query word is for a range of matrix multiplication up, it sets a segment tree maintenance
If that is to reverse the interval 0,1, then directly to the matrix elements to exchange a few good position
I could write ugly, 990ms rubbing his time in the past, when the examination is often the QAQ card
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod (long long)(1e9+7)
int read(){
int num=0;
char ch=getchar();
while(!isdigit(ch)){
ch=getchar();
}
while(isdigit(ch)){
num=num*10+ch-'0';
ch=getchar();
}
return num;
}
ll write(ll x){
if(x<0){putchar('-');x=~(x-1);}
ll s[20],top=0;
while(x){s[++top]=x%10;x/=10;}
if(!top)s[++top]=0;
while(top)putchar(s[top--]+'0');
putchar('\n');
}
struct matrix{
ll a[3][3];
matrix(){a[0][1]=a[0][2]=a[1][0]=a[1][2]=a[2][0]=a[2][1]=0;a[0][0]=a[1][1]=a[2][2]=1;}
};
matrix operator *(matrix a,matrix b){
matrix c;
memset(c.a,0,sizeof(c.a));
for(int i=0;i<3;++i){
for(int j=0;j<3;++j){
for(int k=0;k<3;++k){
c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%mod;
}
}
}
return c;
}
matrix val[400001];
int tag[400001];
char a[200001];
void build(int o,int l,int r){
if(l==r){
if(a[l]=='0'){
val[o].a[1][0]=val[o].a[2][0]=1;
}
else val[o].a[0][1]=val[o].a[2][1]=1;
return;
}
int mid=(l+r)/2;
build(o*2,l,mid);
build(o*2+1,mid+1,r);
val[o]=val[o*2]*val[o*2+1];
}
void swaps(matrix &a){
swap(a.a[0][0],a.a[0][1]);
swap(a.a[1][0],a.a[1][1]);
swap(a.a[2][0],a.a[2][1]);
swap(a.a[0][0],a.a[1][0]);
swap(a.a[0][1],a.a[1][1]);
}
void pushdown(int o){
if(tag[o]){
swaps(val[o*2]),swaps(val[o*2+1]);
tag[o*2]^=1,tag[o*2+1]^=1;
tag[o]=0;
}
}
void update(int o,int l,int r,int L,int R){
if(L<=l&&r<=R){
tag[o]^=1;
swaps(val[o]);
return;
}
pushdown(o);
int mid=(l+r)/2;
if(L<=mid)update(o*2,l,mid,L,R);
if(mid<R)update(o*2+1,mid+1,r,L,R);
val[o]=val[o*2]*val[o*2+1];
}
matrix query(int o,int l,int r,int L,int R){
if(L<=l&&r<=R){
return val[o];
}
pushdown(o);
int mid=(l+r)/2;
matrix ret;
if(L<=mid)ret=ret*query(o*2,l,mid,L,R);
if(mid<R)ret=ret*query(o*2+1,mid+1,r,L,R);
return ret;
}
int main(){
int n,m;
scanf("%d%d%s",&n,&m,a+1);
build(1,1,n);
while(m--){
int opt=read(),l=read(),r=read();
if(opt==1){
update(1,1,n,l,r);
}
else {
matrix tmp=query(1,1,n,l,r);
write((tmp.a[2][1]+tmp.a[2][0])%mod);
}
}
}