日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

牛客练习赛 66

發布時間:2023/12/3 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 牛客练习赛 66 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

A.平方數

討論一下最接近它的兩個平方數即可。

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<cmath> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; int main() {IO;int T=1;//cin>>T;while(T--){ll x;cin>>x;ll y=sqrt(x);ll z=y+1;z*=z;y*=y;if(abs(y-x)<abs(z-x)) cout<<y<<'\n';else cout<<z<<'\n';}return 0; }

B.異或圖

首先我們要知道一個性質x⊕x=0x\oplus x=0xx=0
設起點為sss,終點為ttt,如果存在一條路徑s?>p1?>p2?>pi?>es->p_1->p_2->p_i->es?>p1??>p2??>pi??>e那么說明有以下等式a[s]⊕a[p1]=ka[p1]⊕a[p2]=ka[p2]⊕a[pi]=ka[pi]⊕a[t]=ka[s]\oplus a[p_1]=k \\ a[p_1]\oplus a[p_2]=k \\a[p_2]\oplus a[p_i]=k\\ a[p_i]\oplus a[t]=ka[s]a[p1?]=ka[p1?]a[p2?]=ka[p2?]a[pi?]=ka[pi?]a[t]=k我們不難發現如果有一條路徑能夠使得s?>??>ts->\dots->ts?>??>t說明a[s]⊕a[e]=0/ka[s] \oplus a[e]=0/ka[s]a[e]=0/k,并且明顯如果a[s]⊕a[e]=ka[s] \oplus a[e]=ka[s]a[e]=k答案是111,如果a[s]⊕a[e]=0a[s] \oplus a[e]=0a[s]a[e]=0需要判斷是否有中間點即a[e]⊕ka[e]\oplus ka[e]k是否存在即可,如存在答案是222,否則不存在路徑答案是?1-1?1
剛開始以為2202^{20}220很大數組開不下,用unordered_map存的個數,結果一直T,最后發現數組能開下直接就A了。~。·

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<cstdio> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int N=1100010; int a[N],cnt[N]; int n,q; int main() {scanf("%d%d",&n,&q);for(int i=1;i<=n;i++){scanf("%d",&a[i]);cnt[a[i]]++;}while(q--){int k,st,ed;scanf("%d%d%d",&k,&st,&ed);if((a[st]^a[ed])==k) printf("1\n");else{int x=a[st]^k,y=a[ed]^k;if(x!=y||!cnt[x]) printf("-1\n");else printf("2\n");}}return 0; }

C.公因子

輾轉相除法擴展可得以下式子,然后不難亂搞求解
gcd(a1,a2,a3,…,an)=gcd(a1,a2?a1,a3?a2,…,an?an?1)gcd(a_1,a_2,a_3,\dots,a_n)=gcd(a_1,a_2-a_1,a_3-a_2,\dots,a_n-a_{n-1})gcd(a1?,a2?,a3?,,an?)=gcd(a1?,a2??a1?,a3??a2?,,an??an?1?)

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #pragma GCC optimize(2) #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int N=1100010; ll a[N]; int n; ll gcd(ll a,ll b) {return b?gcd(b,a%b):a; } int main() {IO;int T=1;//cin>>T;while(T--){cin>>n;for(int i=1;i<=n;i++) cin>>a[i];sort(a+1,a+1+n);ll d=a[2]-a[1];for(int i=3;i<=n;i++) d=gcd(d,a[i]-a[i-1]);if(d<0) d=-d;ll res=abs(a[1]/d*d-a[1]);cout<<d<<' '<<res<<'\n';}return 0; }

E.騷區間

參考大佬題解
一般這種區間左右端點都不確定的情況,我們嘗試固定一段點,求另一個端點的可行范圍。
對于i位置作為左端點,考慮如何求右端點的合法區間,由于a[i]是第二小值,在[i+1,n]范圍內第一個小于a[i]的位置是l1,在[i+1,n]范圍內第二個小于a[i]的位置是r1,不難看出對于[l1,r1)范圍滿足左區間限制條件。
對于i位置作為右端點,我們同樣可以如法炮制的求出滿足右端點限制條件的區間(l2,r2]。
我們可以維護一個樹狀數組差分求得答案。

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0) #include<cstdio> #include<vector> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int N=1000010; int a[N],n; struct node {int l,r;int mx,mn; }tree[N*4]; void pushup(int u) {tree[u].mx=max(tree[u<<1].mx,tree[u<<1|1].mx);tree[u].mn=min(tree[u<<1].mn,tree[u<<1|1].mn); } void build(int u,int l,int r) {tree[u]={l,r,0,n+1};if(l==r){tree[u].mx=tree[u].mn=a[l];return;}int mid=l+r>>1;build(u<<1,l,mid),build(u<<1|1,mid+1,r);pushup(u); } int query_min(int u,int l,int r,int x) {if(l>r) return n+1;if(tree[u].mn>=x) return n+1;if(tree[u].l==tree[u].r) return tree[u].l;int mid=tree[u].l+tree[u].r>>1;if(l>mid) return query_min(u<<1|1,l,r,x);else if(r<=mid) return query_min(u<<1,l,r,x);else{if(tree[u<<1].mn<x){int v=query_min(u<<1,l,r,x);return v!=n+1?v:query_min(u<<1|1,l,r,x);}elsereturn query_min(u<<1|1,l,r,x);} } int query_max(int u,int l,int r,int x) {if(l>r) return 0;if(tree[u].mx<=x) return 0;if(tree[u].l==tree[u].r) return tree[u].l;int mid=tree[u].l+tree[u].r>>1;if(l>mid) return query_max(u<<1|1,l,r,x);else if(r<=mid) return query_max(u<<1,l,r,x);else{if(tree[u<<1|1].mx>x) {int v=query_max(u<<1|1,l,r,x);return v?v:query_max(u<<1,l,r,x);}else return query_max(u<<1,l,r,x);} } vector<int> p[N]; int cnt[N]; int lowbit(int x) {return x&-x; } void update(int k,int x) {for(;k<=n;k+=lowbit(k)) cnt[k]+=x; } ll query(int k) {ll now=0;for(;k;k-=lowbit(k)) now+=cnt[k];return now; } int main() {int T=1;//cin>>T;while(T--){scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d",&a[i]);build(1,1,n);ll res=0;for(int i=1;i<=n;i++){int l=query_min(1,i+1,n,a[i]);int r=query_min(1,l+1,n,a[i]);if(l!=n+1) p[l].push_back(i);if(r!=n+1) p[r].push_back(-i);for(auto t:p[i]){if(t>0) update(t,1);else update(-t,-1);}r=query_max(1,1,i-1,a[i]);l=query_max(1,1,r-1,a[i]);res+=query(r)-query(l);}printf("%lld\n",res);}return 0; }

要加油哦~

總結

以上是生活随笔為你收集整理的牛客练习赛 66的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。