中央値を探します
トピックリンク:
https://ac.nowcoder.com/acm/contest/887/E
タイトル説明
いくつかの配列の中央値は、それが事前にソートされた場合には、この配列の真ん中に立っ数とします。配列が偶数の長さを持っている場合、中央値は、2つの中間要素の最小とします。例えば、アレイの中央値\([10,3,2,3,2] \)は 3(すなわち、ある\([2,2、\下線{3}、3,10] \) )。[1,5,8,1]配列の中央値は1である(すなわち、\([1、\下線{1}、5,8] \) )。
最初に、あなたは空のシーケンスを与えられています。N操作があります。i番目の操作は2つの整数を含んでい\(L_iを\)と\(R_iと\) 。これは、追加することを意味\(R_iと-L_iを+ 1 \)の整数を\(L_iを、L_iを+ 1、...、R_iと\)シーケンスに。各操作の後、あなたは、シーケンスの中央値を見つける必要があります。
説明を入力します。
入力の最初の行は、整数含ま\(N \(1 \当量のN \の当量400000)\)上記のように。
次の2行はそれぞれ、それぞれ、次の形式の6つの整数を含みます。
- \(X_1 \ X_2 \ A_1 \ B_1 \ C_1 \ M_1 \)
- \(Y_1 \ Y_2 \ A_2 \ B_2 \ C_2 \ M_2 \)
これらの値は、生成するために使用されている\(L_iを、R_iと\)を次のように:
私たちは、定義します。
- \(X_I \ M_1 \ =(A_1 \時間\モジュールX_ {I-1} + B_1 \時間X_ {I-2} + C_1))をするため、\(I = 3 \ N \を\します)
- \(Y_I \ M_2 \ =(A_2 \時間\モジュールY_ {I-1} + B_2 \時間Y_ {I-2} + C_2))をするため、\(I = 3 \ N \を\します)
また、定義します。
- \(L_iを=分(X_I、Y_I)+ 1 \)のために、\(I = 1 \ N \を\します)。
- \(R_iを= MAX(X_I、Y_I)+ 1 \)のために、\(I = 1 \ N \を\します)。
限界:
\(1 \当量N \の当量400000 \)
\(0 \当量のA_1 <M_1 \)
\(0 \当量のA_2 <M_2 \)
\(0 \当量B_1 <M_1 \)
\(0 \当量B_2 < M_2 \)
\(0 \当量C_1 <M_1 \)
\(0 \当量C_2 <M_2 \)
\(0 \当量X_1 <M_1 \)
\(0 \当量X_2 <M_1 \)
\(0 \当量Y_1 < M_2 \)
\(0 \当量Y_2 <M_2 \)
\(1 \当量M_1 \当量10 ^ 9 \)
\(1 \当量M_2 \当量10 ^ 9 \)
出力説明:
あなたは、出力ラインをする必要があります。各行は、整数の中央値を意味含まれています。
サンプル入力
5
3 1 4 1 5 9
2 7 1 8 2 9
サンプル出力
3
4
5
4
5
説明
L = [3、2、4、1、7]
R = [4,8、8、3、9]
問題の意味
あなたが空のシーケンスを与える、\(N- \)命令は、各時間\(L、R&LTの\)は、発現された配列に加え\(L、L + 1、 \ cdots、Rの\) 合計\(R- L + 1 \)素子、各命令の後の中央値の入力配列。
\(N- \)被験者所与の方法によって生成される命令。
問題の解決策
この問題はない場合は、離散、そして、直接ツリーラインの重みに、ここでの話を離散問題に焦点を当て。
私は個別の場所を感じるようになったときに不可解です。
左と右のオープンを閉じるとき
場合は、右のポイント+1
場合は、右のポイント-1
私たちは、データの集合を考えることを望む可能性があります挿入\((1,1)の\ \(1,5)\ \(5,5)\)
後者は、通常、離散別個のに応じてない場合(\)(1,1)\ \(1,2)\ \(2,2)\
そして、通常のツリーライン、そして見つける\((1,1)+(2,2)\)と\((1,2)\)中間点で同様の効果が、なぜ、しませんでしたか?
ポイントは、左または右のエンドポイントまたは中間点、2点のギャップが原因を特定することができない点である場合には、離散した後、我々は判断できないため。
私のアプローチ:
- このような要求として線分の長さの要件に一緒に接続された離散的な点、\((1,5)\)需要に\((1,6)\) 、このセグメントの長さ\((\)である\(5 )\)
- 各ノードセグメントツリー\((L、R&LT)\) 、実際の管理部である\((L、R + 1 )\)
- ラインに添加した場合、右セグメントツリーは、マルチポイントを管理するため、右1を覚え
そのような\((1、1)\ \(1,5)\ \(5,5)\)となる\((2)\ \(1,6)\ \(5、6)\ )、その後に離散\((2)\ \(4)\ \(3、4)\) 、右端が-1、すなわち、覚えて追加される\((1、1)\ \( 1,3)\ \(3,3)\)値+1、いくつかの間隔権。
\(PS:\)このセクションでは、問題がエンドポイントを考慮すべき多くの問題ですカバーしています。
コード
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 0x7f7f7f7f
#define N 800050
template<typename T>void read(T&x)
{
ll k=0; char c=getchar();
x=0;
while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
if (c==EOF)exit(0);
while(isdigit(c))x=x*10+c-'0',c=getchar();
x=k?-x:x;
}
void read_char(char &c)
{while(!isalpha(c=getchar())&&c!=EOF);}
ll n,num;
ll X[N],Y[N],kth[N];
struct Query{ll l,r;}que[N];
struct Tree{ll l,r,lazy,sum;}tr[N<<2];
void push_up(ll x)
{
ll len=kth[tr[x].r+1]-kth[tr[x].l];
if (tr[x].l==tr[x].r)tr[x].sum=0;
else tr[x].sum=tr[x<<1].sum+tr[x<<1|1].sum;
tr[x].sum+=tr[x].lazy*len;
}
void push_down(ll x)
{
Tree &a=tr[x<<1],&b=tr[x<<1|1];
a.lazy+=tr[x].lazy;
b.lazy+=tr[x].lazy;
tr[x].lazy=0;
push_up(x<<1);
push_up(x<<1|1);
}
void bt(ll x,ll l,ll r)
{
tr[x].lazy=tr[x].sum=0; tr[x].l=l; tr[x].r=r;
if (l==r)return;
ll mid=(l+r)>>1;
bt(x<<1,l,mid);
bt(x<<1|1,mid+1,r);
}
void change(ll x,ll l,ll r)
{
if (l<=tr[x].l&&tr[x].r<=r)
{tr[x].lazy++;push_up(x);return;}
ll mid=(tr[x].l+tr[x].r)>>1;
if (l<=mid)change(x<<1,l,r);
if (mid<r)change(x<<1|1,l,r);
push_up(x);
}
ll query(ll x,ll k)
{
if (tr[x].l==tr[x].r)return kth[tr[x].l]+(k-1)/tr[x].lazy;
push_down(x);
ll ls=tr[x<<1].sum;
if (ls<k)return query(x<<1|1,k-ls);
else return query(x<<1,k);
}
void work()
{
ll A1,B1,C1,A2,B2,C2,M1,M2,sum=0;
read(n);
read(X[1]); read(X[2]); read(A1); read(B1); read(C1); read(M1);
read(Y[1]); read(Y[2]); read(A2); read(B2); read(C2); read(M2);
for(ll i=3;i<=n;i++)X[i]=(A1*X[i-1]+B1*X[i-2]+C1)%M1;
for(ll i=3;i<=n;i++)Y[i]=(A2*Y[i-1]+B2*Y[i-2]+C2)%M2;
for(ll i=1;i<=n;i++)
{
que[i].l=min(X[i],Y[i])+1;
que[i].r=max(X[i],Y[i])+2;
kth[++num]=que[i].l;
kth[++num]=que[i].r;
}
sort(kth+1,kth+num+1);
num=unique(kth+1,kth+num+1)-kth-1;
bt(1,1,num);
for(ll i=1;i<=n;i++)
{
ll l=lower_bound(kth+1,kth+num+1,que[i].l)-kth;
ll r=lower_bound(kth+1,kth+num+1,que[i].r)-kth;
sum+=que[i].r-que[i].l;
change(1,l,r-1);
printf("%lld\n",query(1,(sum+1)/2));
}
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen("aa.in","r",stdin);
#endif
work();
}