2019牛客多校第九場

2021-09-26 05:59:45 字數 3943 閱讀 2025

由題意可設x+y

=kp+

bx+y=kp+b

x+y=kp

+b代入第二個式子中可以得到kpx

+bx−

x2≡c

(mod

kpx+bx-x^2 \equiv c(mod

kpx+bx

−x2≡

c(modp)

p)p)

第一項是p的倍數可以約掉,所以有x2−

bx+c

≡0(m

od

x^2-bx+c \equiv 0(mod

x2−bx+

c≡0(

modp)p)

p)配方得(x−

b2)2

≡b24

−c(m

od

(x-\frac)^2 \equiv \frac-c(mod

(x−2b​

)2≡4

b2​−

c(modp)

p)p)

為了避免除法,兩邊先同乘4,得到(2x

−b)2

≡b2−

4c(m

od

(2x-b)^2 \equiv b^2-4c(mod

(2x−b)

2≡b2

−4c(

modp)p)

p)直接套用二次剩餘的板子即可

注意這裡得出來的答案的奇偶性(正負性),比如算出來的答案是ans

ansan

s那麼2x−

b=an

s2x-b=ans

2x−b=a

ns有可能解出來的x不是乙個整數,這時候通過變換2x−

b=mo

d−an

s2x-b=mod-ans

2x−b=m

od−a

ns就有整數解了(因為mod是乙個奇數)

(mod-ans本質上是對ans取負)

#include

#define fo(i,a,b) for(i=a;i<=b;i++)

using namespace std;

int t;

long

long mod,x,y,b,c,t;

/*long long pow_mod(long long a,long long x,long long mod)

return ans;

}*/long

long

pow_mod

(long

long a,

long

long i,

long

long n)

long

long

modsqr

(long

long a,

long

long n)

while

(i %2==

0); x =

(pow_mod

(a,(i+1)

/2,n)*

pow_mod

(b,k/

2,n)

)%n;}if

(x*2

>n) x = n - x;

return x;

}return-1

;}intmain()

printf

("%lld %lld\n"

,x,y);}

return0;

}

顯然這裡要用到主席樹維護區間k大值以及這k個數的和

二分答案ans

ansan

s,然後在主席樹上找比這個答案高的竹子的個數num

numnu

m和這些竹子的總高度sum

sumsu

m這一步之需要不斷用ans

ansan

s和中間竹子的高度比較,然後選擇左遞迴或右遞迴即可

那麼當前砍下來的竹子的高度應該就是sum

−ans

∗num

sum-ans*num

sum−an

s∗nu

m實際上並不需要二分答案,只需要跑一次主席樹也可以

對於當前節點,如果把左子樹全部砍掉答案足夠了那麼就左遞迴,如果不夠就右遞迴

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define inf 1000000000

#define mod 1000000007

#define n 200005

using namespace std;

int a[n]

,b[n]

,root[n*20]

,ls[n*20]

,rs[n*20]

,num[n*20]

;long

long sum[n*20]

,pre[n]

;int n,q,i,tot,k,ql,qr,pp,qq;

double l,r,mid;

void

build

(int l,

int r,

int&rt)

void

update

(int l,

int r,

int&rt,

int last,

int p)

intquery1

(int ss,

int tt,

int l,

int r,

double x)

long

long

query2

(int ss,

int tt,

int l,

int r,

double x)

bool check

(double x)

intmain()

printf

("%.10lf\n"

,l);

}return0;

}

為了避免出現小數依然是先乘2

然後考慮每一塊對每一條對稱軸的貢獻

比如某一塊的座標是[2,8],那麼在y=2的貢獻是0,y=3的貢獻是2,y=4的貢獻是4…以此類推

所以貢獻一定是一段遞增然後一段遞減

差分一次之後就是兩段相同的數

差分兩次之後就是三個數,分別是2 -4 2

累加之後再恢復到初始狀態即可

#include

#define fo(i,a,b) for(i=a;i<=b;i++)

#define n 300005

using namespace std;

struct node f[n*3]

;int n,i,k;

long

long res,sum1,sum2;

int l[n]

,r[n]

,pos[n*3]

,v[n*3]

;bool cmp

(const node &a,

const node &b)

intmain()

sort

(f+1

,f+k+

1,cmp)

; n =0;

fo(i,

1,k)

if(f[i]

.pos != f[i-1]

.pos)

else v[n]

+= f[i]

.v; res =

0; sum1 =

0; sum2 =0;

fo(i,

1,n-1)

cout<2<}

牛客多校第九場補題(待完善)

i the crime solving plan of groundhog 題目大意 給定一組由 0 9 組成的數,組成兩個數使乘積最小。解題思路 用陣列儲存 0 9 的個數,先從 1 9 選最小的作為其中乙個乘數,其餘的數組成所能表達的最小的數。難點應該是大數乘法 這個也不難 include in...

2019 杭電多校(第九場)

1002 rikka with cake 思維 題意給你乙個蛋糕 問你切k刀後分成多少塊 思路塊數 交點數 1 樹狀陣列維護橫線有多少條 豎線去統計 隊友 include define ll long long using namespace std struct code tree 500005 ...

牛客多校第九場部分題題解

include using namespace std typedef long long ll ll n,m int f 50000000 intqpow ll a,int b,int p return ret ll inv ll a,ll p ll findr int p while f i 1...