T1
A. 。。これは、水問題です。。個人的な感情は、それだけでUPPER_BOUNDうまくQAQを行うということです
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn=300000;
const int inf=1e9;
int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,a[maxn+10],limit;
long long ans=0;
int main(){
freopen("dwar.in","r",stdin);
freopen("dwar.out","w",stdout);
n=read();limit=read();
for(int i=1;i<=n;i++) a[i]=read();
sort(a+1,a+1+n);a[++n]=inf;
for(int i=1,pos;i<=n-1;i++){
if(limit>=a[i]*2){
pos=upper_bound(a+i,a+1+n,limit-a[i])-a;
if(pos>i){
ans=ans+(long long)pos-(long long)i-1;
}
}
}
printf("%lld",ans);
}
T2
この質問は私のような人々が弱いという結論をプッシュするためには適していません。実際に、私は結論をプッシュする場合でも、私は組み合わせQAQの数を数えることができません
約最初の話(70ptsは\)\アルゴリズムこのデータには明らかであろう((N ^ 2)O \ \) ので、2つの次元を考慮を通じて(DP \)\ \(dp_ {I、Jは} \) 最初に電流を表す\ (I \)ビット、及び現在位置(現在位置が必要)を含む全選択した\(J \)の数。明らか場合にのみ(i≡j(MOD2)\)\時間、\(dp_ {I、Jは} \)の値を有することになります
検討は慎重により求めた\(DP [I] [J ] = \ sum_ {k = 0} ^ {I> 2K} DP [I-2K-1] [J-1] \) しかし、これは3つ必要\( \)のためにループがハングします。次いで、驚くべき(DP [I-2] \ [J] = \ sum_ {k = 0} ^ {I-2> 2K} DP [I-2K-3] [J-1] \) したがって\( DP [I] [J] = DP [I-1] [J-1] + DP [I-2] [J] \)
あなたが得ることができるように\(70ptsを\)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn=2010;
const int mod=998244353;
int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int dp[maxn][maxn],n,m,t,ans;
int main(){
freopen("temple.in","r",stdin);
freopen("temple.out","w",stdout);
for(int i=0;i<=2000;i++)
dp[i][0]=1;
dp[1][1]=1;
for(int i=2;i<=2000;i++){
for(int j=1;j<=i;j++){
if(j%2==i%2){
dp[i][j]=(dp[i-1][j-1]+dp[i-2][j])%mod;
}
else{
dp[i][j]=0;
}
}
}
t=read();
while(t--){
n=read();m=read();
if(n%2==m%2)
ans=dp[n][m];
else ans=dp[n-1][m];
printf("%d\n",(ans%mod+mod)%mod);
}
}
これは、アルゴリズムのアウトです:それを考える人々との問題があることは明らかである(a_iを+ I \)は\偶数でなければなりません。\(1 <= a_iを+ I <= N + M \)は、 と等価である\([1、N + M ]が\) も内側Mから選択されましたか??このように、\(a_iを+ I \)は QAQを考える方法です
その後、答えはと等価である(\ displaystyle \ binom {\ \ lfloor \ FRAC {N + M} {2} \ rfloor} {M} \) オーダー\(\ displaystyle X = \ lfloor \ FRAC {N + M} { 2} \ rfloor、Y = M \) である\(\ displaystyle \ FRAC {X !} {Y!(XY)!} \%MOD \) の数を乗じた以外は、彼の逆数に等しく、これはシークと同等です\(Y!(XY)が !\) 、その後、あなたがそれを行うことができ、ほぼ逆です。。。これ?
この質問は毎回反転元の爆発どうやら本当の母親、以上尋ねたので、私たちは前処理を検討しています。。リニアQAQを反転します
\(* A ^ { - 1}≡b* B ^ { - 1} \(MOD P)\) 転置に与える\(^ { - 1} ≡b^ { - 1} *(\ FRAC {B } {})\)この質問に、もし!! \(B = I、 =(I-1)\) 次に\((I-1)^ { - !1} = I ^ {! -1} * I \)その後、\(1E6 ^ { - !1 } \) フェルマーの小定理はちょうどうまくいじりを持ちます。
また、ノート:線形逆ドルは明確であるかのように、得られていない(A、B \)\割り切れない、私はGGでこれを推測し、線形逆元正しい導出はこれです:
セット\(÷B = Q ...... R \)
\(q⋅b+r≡0(モーダ) \) 略同時に乗じ\(B ^ { - 1} \ CDOT R ^ { - 1} \)
\(q⋅r^ { - 1} + B ^ { - 1}≡0(MODP)\)
\(B ^ { - 1}≡-q⋅r{-1}(MODP)\)
\(B ^ { - 1}≡-⌊\ FRACab⌋⋅(amodb)^ { - 1}(ファッション)\)
\(B ^ { - 1}≡a-⌊\ FRACab⌋⋅(amodb)^ { - 1}(ファッション)\)
。。明らかに、この質問は前式のこの導出でもあるが、それは使用する方が便利だと思われます
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define LL long long
using namespace std;
const int maxn=1e6;
const int mod=998244353;
int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int factorial[maxn+10],inv[maxn+10],t;
LL ksm(int x,int y){
LL sum=1;
while(y){
if(y&1) sum=(long long)sum*x%mod;
y>>=1;x=(long long)x*(long long)x%mod;
}
return sum%mod;
}
void prepare_work(int x){
factorial[0]=1;
for(int i=1;i<=maxn;i++) factorial[i]=(long long)factorial[i-1]*i%mod;
inv[maxn]=(int)ksm(factorial[maxn],mod-2);
for(int i=maxn-1;i>=0;i--){
inv[i]=(long long)inv[i+1]*(i+1)%mod;
}
}
int n,m;
long long C(int x,int y){
return (long long)factorial[y]*inv[x]%mod*inv[y-x]%mod;
}
int main(){
prepare_work(maxn);
t=read();
while(t--){
n=read();m=read();
printf("%lld\n",C(m,(n+m)/2));
}
return 0;
}
T3
我々は尋ねたよう\([X、Y]を\ ) 間隔は、現在のノード依頼する\([L、R]を\ ) 、次いで4例合計に分割現在の間隔のために:
1.現在の間隔が完全に範囲ASK含まれています明らかに、すべてのサブ範囲の間隔を尋ねたが、現在のレンジに貢献しています
2.断面の電流範囲と真実尋ねる:十分考慮しなければならない、算術配列加算式の数を忘れることができると、コードは非常に明確であるはず
次の議論のための待機:3.間隔を掲載し、完全に現在の範囲が含まれています
4.交差点の現在の間隔で間隔を尋ねると、空ではありません。何も貢献
だから今第三のシナリオを議論します:
(すなわち、そこに分解することができるこの前処理、またはセグメントツリーが底部にトラバースされる考える)\(O(^ N-2)\)
現在のノード、2つの方法で解答への貢献のために:それを介してノードとして、その終端ノードとして
それは、ノードにその貢献として渡した場合:呼び掛けゾーンと現在の間隔交差し、そして現在の範囲が含まれていない区間をお願いします。
次いでかわいい手書きの単語との寄与が出ている:\((RL)が\ CDOT(L-R&LT-QL + QRある)+ \ FRAC {(R1は+ 1)\ CDOT(RL + 2)です。} { 2} \)
これは、終端ノードかのように、その後に貢献される:完全に現在の間隔間隔の数が含まれているが、\( - \)完全な間隔の父親間隔数を含まれています
我々はリーフノードマークされた場合は、\(+ 1 \)のマーク、他のすべてのマーク( - 1 \)\マーク、少し包含と除外をそれが総寄与率ことを発見し、そのサブツリーの現在のノードおよびすべてのノードのサブツリーがあることができます係数。
それはおそらくないですQAQ
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define int long long
using namespace std;
const int maxn=1000;
int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int kx[maxn<<2],ky[maxn<<2],kxy[maxn<<2],b[maxn<<2];
int n,q,opt,lastans;
void build(int node,int l,int r){
if(l==r){
kx[node]+=r-1;ky[node]+=l+1;
kxy[node]--;b[node]=(l-r+1-l*r);
return ;
}
kx[node]-=(r-1);ky[node]-=(l+1);
kxy[node]+=1;b[node]-=(l-r+1-l*r);
kx[node]+=(l-r);ky[node]+=(r-l);
b[node]+=(r-l+1)*(r-l+2)/2-1;
b[node]+=(2*r*l-l*l-r*r);
int mid=l+r>>1;
build(node<<1,l,mid);build(node<<1|1,mid+1,r);
kx[node]+=kx[node<<1]+kx[node<<1|1];
ky[node]+=ky[node<<1]+ky[node<<1|1];
kxy[node]+=kxy[node<<1]+kxy[node<<1|1];
b[node]+=b[node<<1]+b[node<<1|1];
}
int query(int node,int l,int r,int ql,int qr){
if(ql<=l && r<=qr){
int ans=0;
ans+=kx[node]*ql;ans+=ky[node]*qr;ans+=kxy[node]*ql*qr;ans+=b[node];
return ans;
}
if(l<=ql && qr<=r){
int mid=l+r>>1,ans=0;
ans=(qr-ql+1)*(qr-ql+2)/2;
if(ql<=mid) ans+=query(node<<1,l,mid,ql,qr);
if(mid<qr) ans+=query(node<<1|1,mid+1,r,ql,qr);
return ans;
}
int ans=0,mid=l+r>>1;
if(ql<l) ans+=(qr-ql+1+l-ql+1)*(qr-l+1)/2;
if(r<qr) ans+=(qr-ql+1+qr-r+1)*(r-ql+1)/2;
if(ql<=mid) ans+=query(node<<1,l,mid,ql,qr);
if(mid<qr) ans+=query(node<<1|1,mid+1,r,ql,qr);
return ans;
}
signed main(){
n=read();q=read();opt=read();
build(1,1,n);
for(int i=1,x,y;i<=q;i++){
x=read();y=read();
x=(x^(lastans*opt))%n+1;y=(y^(lastans*opt))%n+1;
if(x>y) swap(x,y);
lastans=query(1,1,n,x,y);
printf("%lld\n",lastans);
}
return 0;
}