1001: Inversion
Template question: Find Reverse Order Number pairs. You can cut the number of Reverse Order pairs.
1003: least common multiple
For each subset, LCM is the maximum power of A of 2 x the maximum power of B of 3.
So we only need to find the distribution of the maximum value of a when B is the maximum value of B.
We first sort B from small to large.
For a certain B, we only need to find the number of A which is smaller than current A as X;
Then we can see that the subset of these a is 2 ^ X, and the maximum value of each subset A is current.
I still need to find out how many numbers a greater than a are smaller than a. We can use the line segment tree for gradual maintenance.
#include <iostream>#include<stdio.h>#include<vector>#include<queue>#include<stack>#include<string.h>#include<algorithm>#include<math.h>#include<map>using namespace std;#define LL long long#define lcm(a,b) (a*b/gcd(a,b))#define maxn 110000#define lson l,(l+r)/2,rt<<1#define rson (l+r)/2+1,r,rt<<1|1struct list{ int a,b; friend bool operator <(const list &a,const list &b) { return a.b<b.b; }}p[maxn];int cmp(list a,list b){ return a.a<b.a;}int ed[maxn];LL num[maxn<<2];LL sum[maxn<<2];LL lazy[maxn<<2];void push_down(int rt){ if(lazy[rt]!=1) { sum[rt<<1]*=lazy[rt]; sum[rt<<1|1]*=lazy[rt]; sum[rt<<1]%=mod; sum[rt<<1|1]%=mod; lazy[rt<<1]*=lazy[rt]; lazy[rt<<1|1]*=lazy[rt]; lazy[rt<<1]%=mod; lazy[rt<<1|1]%=mod; lazy[rt]=1; }}void push_up(int rt){ sum[rt]=sum[rt<<1]+sum[rt<<1|1]; num[rt]=num[rt<<1]+num[rt<<1|1]; sum[rt]%=mod;}void creat(int l,int r,int rt){ num[rt]=sum[rt]=0; lazy[rt]=1; if(l!=r) { creat(lson); creat(rson); return; }}void insert(int x,int l,int r,int rt){ if(x<l||x>r)return; if(l==r&&l==x) { num[rt]++; sum[rt]=M.q_mod(2,ed[x],mod); sum[rt]=(sum[rt]*lazy[rt])%mod; return; } push_down(rt); insert(x,lson); insert(x,rson); push_up(rt);}void updata(int ll,int rr,int l,int r,int rt){ if(ll>rr)return ; if(ll>r||rr<l)return; if(ll<=l&&rr>=r) { lazy[rt]*=2; sum[rt]=sum[rt]*2%mod; return; } push_down(rt); updata(ll,rr,lson); updata(ll,rr,rson); push_up(rt);}LL query(int ll,int rr,int leap,int l,int r,int rt){ if(ll>rr)return 0; if(ll>r||rr<l)return 0; if(ll<=l&&rr>=r) { if(leap==0)return num[rt]; else return sum[rt]; } push_down(rt); return query(ll,rr,leap,lson)+query(ll,rr,leap,rson);}int main(){ int n; while(~scanf("%d",&n)) { for(int i=1;i<=n;i++) { scanf("%d%d",&p[i].a,&p[i].b); } sort(p+1,p+n+1,cmp); for(int i=1;i<=n;i++) { ed[i]=p[i].a; p[i].a=i; } creat(1,n,1); sort(p+1,p+n+1); LL sum=0; for(int i=1;i<=n;i++) { int k=p[i].a; LL x=query(1,k-1,0,1,n,1); LL y=query(k+1,n,1,1,n,1); LL now=M.q_mod(3,p[i].b,mod); LL ps=((M.q_mod(2,ed[k],mod))*(M.q_mod(2,x,mod)))%mod; sum+=now*((ps+y)%mod)%mod; insert(k,1,n,1); updata(k+1,n,1,n,1); sum=sum%mod; } cout<<sum<<endl; } return 0;}
1005: parenthese Sequence
My practice does not seem to be a serious practice... Sad
First, match each of them (if no match is found, match the first ?, If it cannot be matched, there is no solution.
After a match, there is still (and ?.
Match the rest of each (matching the last ?; If not ?, Certainly no solution.
Suppose there are X ?;
If X is an odd number, there is no solution.
If X is 0, it must be unique.
If X> 2, there must be multiple solutions.
If X = 2, then the first? Set to), second? Set to (. If it is trusted, multiple solutions are available. Otherwise, the only solution is available.
#include <iostream>#include<stdio.h>#include<vector>#include<queue>#include<stack>#include<string.h>#include<algorithm>#include<map>using namespace std;#define LL long long#define gcd(a,b) (b==0?a:gcd(b,a%b))#define lcm(a,b) (a*b/gcd(a,b))int pre[1100000];int next[1100000];char str[1100000];stack<int>st;stack<int>we;int biao[1100000];int fbiao[1100000];int main(){ while(~scanf("%s",str)) { while(!st.empty())st.pop(); while(!we.empty())we.pop(); memset(pre,-1,sizeof(pre)); memset(next,-1,sizeof(next)); int len=strlen(str); int last=-1; int leap=0; int sts=-1; for(int i=0;i<len;i++) { if(str[i]=='(') { st.push(i); } else if(str[i]==')') { if(st.empty()) { leap=1; if(sts==-1) { leap=-1; break; } else { str[sts]='('; sts=next[sts]; if(sts==-1) { pre[sts]=-1; sts=last=-1; } else pre[sts]=-1; } } else { int x=st.top(); st.pop(); } } else if(str[i]=='?') { pre[i]=last; if(sts==-1)sts=i; else next[last]=i; last=i; // cout<<sts<<endl; } } if(leap==-1) { cout<<"None"<<endl; continue; } while(!st.empty()) { if(last==-1) { break; } int x=st.top(); if(x<last) { st.pop(); str[last]=')'; last=pre[last]; } else break; } int ss=0; while(last!=-1) { last=pre[last]; ss++; } // cout<<ss<<endl; if(leap==-1||!st.empty()||ss%2) { cout<<"None"<<endl; continue; } if(ss>2) { cout<<"Many"<<endl; continue; } if(ss==0) { cout<<"Unique"<<endl; continue; } while(!st.empty())st.pop(); int lp=0; leap=1; // cout<<str<<endl; for(int i=0;i<len;i++) { if(str[i]=='?') { if(lp==0) { str[i]=')'; lp++; } else str[i]='('; } } // cout<<str<<endl; int i; for(i=0;i<len;i++) { if(str[i]=='(')st.push(i); else if(str[i]==')') { if(st.empty())break; else st.pop(); } } if(i<len)cout<<"Unique"<<endl; else cout<<"Many"<<endl; } return 0;}
1009: exclusive or
Because the result is an exclusive or sum of numbers.
We can enumerate which numbers are different or come from when each digit is 1.
For the current BIT, if A and B are exclusive or the result is 1, then the current bit of the numbers A and B is 1 and one is 0. There are two cases in total.
A + B = N is known.
X can be obtained for the sum of the numbers before the current bit, and y can be obtained for the sum of the numbers after the current BIT.
There are always two cases: x * y.
Because both A and B are non-0, we need to subtract 0.
Because it is a large number... So it is too hard to use Java and C ++ for large numbers ..
import java.util.Scanner;import java.math.*;public class Main { public static void main(String[] args) { Scanner cin = new Scanner(System.in); BigInteger n,m,sum,zero,one,two,x,k,y,ta,tb,z; BigInteger bit[] = new BigInteger[3300]; bit[0] = BigInteger.valueOf(1); int i; for(i = 1;i <= 3000;i ++) bit[i] = bit[i-1].multiply(BigInteger.valueOf(2)); zero = BigInteger.valueOf(0); one = BigInteger.valueOf(1); two = BigInteger.valueOf(2); while(cin.hasNext()) { n = cin.nextBigInteger(); m = n; sum = BigInteger.valueOf(0); for(i = 1;;i ++) { n = m.subtract(bit[i-1]); if(n.compareTo(zero) == -1) break; x=n.divide(bit[i]).add(one); k=n.mod(bit[i]); if(bit[i-1].subtract(one).compareTo(k) == -1) ta = bit[i-1].subtract(one); else ta = k; if(zero.compareTo(k.subtract(bit[i-1]).add(one)) == 1) tb = zero; else tb = k.subtract(bit[i-1]).add(one); y=ta.subtract(tb).add(one); sum = sum.add(x.multiply(y).multiply(two).multiply(bit[i-1])); z = m.divide(bit[i]); k = m.divide(bit[i-1]); z = z.multiply(two); if(k.compareTo(z) != 0) { sum = sum.subtract(bit[i-1].multiply(two)); } } System.out.println(sum); } }}
1010: Matrix Multiplication
In this case, we can remove all the zeros and then proceed...
The theoretical time complexity is 800*800*800 * (2/3) * (2/3)
# Include <iostream> # include <stdio. h> # include <vector> # include <queue> # include <stack> # include <string. h ># include <algorithm> # include <map> using namespace STD; # define ll long # define gcd (A, B) (B = 0? A: gcd (B, A % B) # define lcm (a, B) (a * B/gcd (a, B) // O (n) Evaluate the prime number, 1-N records # define n 100010 // a ^ x = a ^ (X % PHI (c) + PHI (c) (mod C) int A [880] [880]; int B [880] [880]; int AA [880] [880]; int BB [880] [880]; int C [880] [880]; int main () {int N; while (~ Scanf ("% d", & N) {memset (A, 0, sizeof (a); memset (B, 0, sizeof (B); memset (AA, 0, sizeof (AA); memset (BB, 0, sizeof (bb); memset (C, 0, sizeof (c); For (INT I = 1; I <= N; I ++) {for (Int J = 1; j <= N; j ++) {scanf ("% d ", & A [I] [J]); A [I] [J] % = 3 ;}}for (INT I = 1; I <= N; I ++) {for (Int J = 1; j <= N; j ++) {scanf ("% d", & B [I] [J]); B [I] [J] % = 3 ;}for (INT I = 1; I <= N; I ++) {int x =-1; for (Int J = N; j> = 0; j --) {AA [I] [J] = x; if (a [I] [J]) X = J ;}} fo R (INT I = 1; I <= N; I ++) {int x =-1; for (Int J = N; j> = 0; j --) {BB [I] [J] = x; If (B [I] [J]) x = J ;}} for (INT I = 1; I <= N; I ++) {for (Int J = AA [I] [0]; J! =-1; j = AA [I] [J]) {for (int K = BB [J] [0]; k! =-1; k = BB [J] [k]) c [I] [k] + = A [I] [J] * B [J] [k] ;}} for (INT I = 1; I <= N; I ++) {for (Int J = 1; j <= N; j ++) {printf ("% d", C [I] [J] % 3 ); if (J! = N) printf (""); else printf ("\ n") ;}} return 0 ;}