2017ACM-ICPC廣西邀請賽-重現賽
這是在厚林工作室4個人打的一場
騷呢
兩年沒回去了
拿lzy的號打,打的被老劉查水錶了
01
列舉,。
看到我的就知道我是怎麼wa的了。。
#include <bits/stdc++.h> using namespace std; typedef long long ll; ll powder(ll a,ll n){ if(n==0) return 1ll; ll ret = powder(a,n/2); ret = ret * ret; if(n&1) return ret*a; return ret; } int main(){ int T; ll n; while(cin>>n){ int cnt = 0; for(ll i=1;i<=15;i++){ if(powder(i,i)<=n) cnt++; } cout<<cnt<<endl; } return 0; }
#02 Color it
線段樹,按y排,存x座標,維護min
按x排存y座標也行的,
防止炸空間,可以離散化或者像我這樣,用到哪建到哪,最多是nlogn的
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N = 1e6 + 7; bool getCol; struct segTree{ #define val(x) tree[x].val #define lson tree[rt].lc, l, m #define rson tree[rt].rc, m+1, r static const int TREE_N = N * 3 + 3e5; struct node{ int lc, rc, val; } tree[TREE_N]; int tot, root[55]; void build(){ memset(tree, 0, sizeof(tree)); memset(root, 0, sizeof(root)); tot = 0; } //p: pos, v: val void add(int p, int v, int &rt, int l, int r){ if (!rt) val(rt = ++tot) = v; val(rt) = min(val(rt), v); if (l == r) return; int m = (l + r) >> 1; if (p <= m) add(p, v, lson); else add(p, v, rson); } void query(int L, int R, int v, int rt, int l, int r){ if(getCol || !rt) return; if(L <= l && r <= R){ if(val(rt) <= v) getCol = 1; return; } int m = (l + r) >> 1; if (L <= m) query(L, R, v, lson); if (R > m) query(L, R, v, rson); } #undef val(x) #undef lson #undef rson } T; int main(){ //freopen("in.txt", "r", stdin); int op, x, y, c, L, R, X; T.build(); for (; scanf("%d", &op) && op != 3;){ if (op == 0) T.build(); else if(op == 1){ scanf("%d%d%d", &x, &y, &c); T.add(y, x, T.root[c], 1, N); }else if(op == 2){ scanf("%d%d%d", &X, &L, &R); int ans = 0; for(int i = 0; i <= 50; i++){ getCol = 0; T.query(L, R, X, T.root[i], 1, N); if (getCol) ans++; } printf("%d\n",ans); } } return 0; }
03
統計有多少,。
考慮一個邊作為對角線時,如果有K個點跟這個邊的兩個端點都相連,那麼有中方案。
統計時,讓條邊記錄在度數比較少的點處,減少列舉次數,每次將3個邊一起算貢獻。
#include <bits/stdc++.h> #define mp make_pair using namespace std; typedef long long ll; const int maxn = 100005; vector<pair<int,int> > e[maxn]; int du[maxn],u,v,n,m; ll cnt[maxn<<2]; struct node{ int u,v; }info[maxn<<2]; struct Node{ int idi,idep; Node(){} Node(int _idi,int _idep){ idi=_idi; idep=_idep; } }a[maxn<<2]; int main(){ while(~scanf("%d%d",&n,&m)){ for(int i=1;i<=n;i++) e[i].clear(); memset(a,0,sizeof a); memset(du,0,sizeof du); for(int i=1;i<=m;i++){ scanf("%d%d",&u,&v); du[u]++;du[v]++; info[i].u=u; info[i].v=v; } for(int i=1;i<=m;i++){ u=info[i].u;v=info[i].v; if(du[u] < du[v] || (du[u] == du[v] && u < v)) e[u].push_back(mp(v,i)); else e[v].push_back(mp(u,i)); } memset(cnt,0,sizeof cnt); for(int i=1;i<=m;i++){ u=info[i].u;v=info[i].v; for(auto ep:e[u]) a[ep.first]=Node(i,ep.second); for(auto ep:e[v]){ if(a[ep.first].idi==i){ cnt[i]++; cnt[ep.second]++; cnt[a[ep.first].idep]++; } } } ll res = 0; for(int i=1;i<=m;i++) res += (cnt[i]-1ll)*cnt[i]/2ll; printf("%lld\n",res); } return 0; }
04
Number of domino tilings of 4 X (n-1) board.
,直接用杜教板子。。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <cassert>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll mod=1000000007;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
// head
int _;
ll n;
namespace linear_seq {
const int N=10010;
ll res[N],base[N],_c[N],_md[N];
vector<ll> Md;
void mul(ll *a,ll *b,ll k) {
rep(i,0,k+k) _c[i]=0;
rep(i,0,k) if (a[i]) rep(j,0,k) _c[i+j]=(_c[i+j]+a[i]*b[j])%mod;
for (int i=k+k-1;i>=k;i--) if (_c[i])
rep(j,0,SZ(Md)) _c[i-k+Md[j]]=(_c[i-k+Md[j]]-_c[i]*_md[Md[j]])%mod;
rep(i,0,k) a[i]=_c[i];
}
int solve(ll n,VI a,VI b) {
ll ans=0,pnt=0;
ll k=SZ(a);
assert(SZ(a)==SZ(b));
rep(i,0,k) _md[k-1-i]=-a[i];_md[k]=1;
Md.clear();
rep(i,0,k) if (_md[i]!=0) Md.push_back(i);
rep(i,0,k) res[i]=base[i]=0;
res[0]=1;
while ((1ll<<pnt)<=n) pnt++;
for (int p=pnt;p>=0;p--) {
mul(res,res,k);
if ((n>>p)&1) {
for (int i=k-1;i>=0;i--) res[i+1]=res[i];res[0]=0;
rep(j,0,SZ(Md)) res[Md[j]]=(res[Md[j]]-res[k]*_md[Md[j]])%mod;
}
}
rep(i,0,k) ans=(ans+res[i]*b[i])%mod;
if (ans<0) ans+=mod;
return ans;
}
VI BM(VI s) {
VI C(1,1),B(1,1);
int L=0,m=1,b=1;
rep(n,0,SZ(s)) {
ll d=0;
rep(i,0,L+1) d=(d+(ll)C[i]*s[n-i])%mod;
if (d==0) ++m;
else if (2*L<=n) {
VI T=C;
ll c=mod-d*powmod(b,mod-2)%mod;
while (SZ(C)<SZ(B)+m) C.pb(0);
rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
L=n+1-L; B=T; b=d; m=1;
} else {
ll c=mod-d*powmod(b,mod-2)%mod;
while (SZ(C)<SZ(B)+m) C.pb(0);
rep(i,0,SZ(B)) C[i+m]=(C[i+m]+c*B[i])%mod;
++m;
}
}
return C;
}
int gao(VI a,ll n) {
VI c=BM(a);
c.erase(c.begin());
rep(i,0,SZ(c)) c[i]=(mod-c[i])%mod;
return solve(n,c,VI(a.begin(),a.begin()+SZ(c)));
}
};
int main() {
while(~scanf("%lld",&n)){
printf("%d\n",linear_seq::gao(VI{1,1, 5, 11, 36, 95, 281, 781, 2245, 6336, 18061, 51205, 145601, 413351, 1174500, 3335651, 9475901, 26915305, 76455961, 217172736},n));
}
}
05
求三種sum丟掉第k位
預處理出所有的字首和字尾
黑康說:按位列舉???
#include <cstdio>
#include <iostream>
using namespace std;
const int N = 1e5 + 7;
int arr[N];
int prXor[N], prAnd[N], preOr[N];
int suXor[N], suAnd[N], sufOr[N];
int main(){
//freopen("in.txt", "r", stdin);
int n, q;
for (; ~scanf("%d%d", &n, &q);){
prXor[0] = suXor[n+1] = 0;
prAnd[0] = suAnd[n+1] = ~0;
preOr[0] = sufOr[n+1] = 0;
//printf("%d\n", prAnd[0]);
for (int i = 1; i <= n; i++){
scanf("%d", &arr[i]);
prXor[i] = prXor[i-1] ^ arr[i];
prAnd[i] = prAnd[i-1] & arr[i];
preOr[i] = preOr[i-1] | arr[i];
}
for (int i = n; i >= 1; i--){
suXor[i] = suXor[i+1] ^ arr[i];
suAnd[i] = suAnd[i+1] & arr[i];
sufOr[i] = sufOr[i+1] | arr[i];
}
for (int k; q--;){
scanf("%d", &k);
int ansXor = prXor[k-1] ^ suXor[k+1];
int ansAnd = prAnd[k-1] & suAnd[k+1];
int ansOrr = preOr[k-1] | sufOr[k+1];
printf("%d %d %d\n", ansAnd, ansOrr, ansXor);
}
}
return 0;
}
06
好像是個傻逼題,然後犯了傻逼錯誤
貢獻了-6的罰時,
國王的座標給的那麼噁心的數字,就是告訴你,國王不會在wall上,然後要讓國王能到達任意地方,就要讓這些wall無法形成環就可以了,所以,不是環,樹嘛,要求刪去的最少,求個最大生成樹,然後,
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define fi first
#define se second
using namespace std;
typedef pair<int, int> P;
const int N = 1e5 + 7;
struct Edge{
int from,to,w;
Edge(){}
Edge(int x,int y,int z):from(x),to(y),w(z){}
bool operator < (const Edge& a) const{return w > a.w;}
} edges[N * 2];
int f[N];
int F(int x){return f[x]==x ? x : (f[x]=F(f[x]));}
bool vis[N];
P kruskal(int n, int m){
int treenum = n; //forests
for (int i = 1;i <= n; i++) f[i] = i;
sort(edges, edges + m);
int cnt = 0, ans = 0;
for (int i = 0; i < m; i++){
Edge &e = edges[i];
if (F(e.from) == F(e.to)) continue;
f[F(e.from)] = F(e.to);
treenum--;
ans += e.w;
}
return P(treenum, ans);
}
int main(){
//freopen("in.txt", "r", stdin);
int n, x, y, u, v, c, m;
for (; scanf("%d%d", &n, &m)==2;){
for (int i = 1; i <= n; i++) scanf("%d%d", &x, &y);
int all = 0;
for (int i = 0; i < m; i++){
scanf("%d%d%d", &u, &v, &c);
edges[i] = Edge(u, v, c);
all += c;
}
P p = kruskal(n, m);
printf("%d %d\n", m-(n-p.fi), all - p.se);
}
return 0;
}
07毛對子和毛順子
貪心:取i,i-1,i-2這個順子的時候先把i-1,i-2的對子取掉,取完再取i的對子
#include <bits/stdc++.h>
using namespace std;
int a[1000005],x,n;
int main(){
while(~scanf("%d",&n)){
memset(a,0,sizeof a);
for(int i=1;i<=n;i++){
scanf("%d",&x);
a[x]++;
}
int cnt = 0;
for(int i=1;i<=1000000;i++){
if(i>=3)
if(a[i] && a[i-1] && a[i-2]){
a[i]--;a[i-1]--;a[i-2]--;
cnt++;
}
cnt += a[i]/2;
a[i] %= 2;
}
printf("%d\n",cnt);
}
return 0;
}
08
開始打表的時候發現如果a是奇數的時候肯定是1
然後a是偶數的時候,2的因子個數很多,列舉一下就行了,後面的就為0了。
開始打表發現,的時候,幾乎是所有的偶數,無腦了幾發。發現的時候答案不對。事實上,列舉一下較小的部分。加上後面0的部分。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,a;
ll power(ll a,ll b,ll mod){
if(b==0) return 1ll;
ll ret = power(a,b/2,mod);
ret = ret * ret % mod;
if(b&1)
return ret*a%mod;
return ret;
}
ll up(ll n,ll a){
return (n + a - 1) / a;
}
int main(){
//freopen("output.txt","w",stdout);
while(~scanf("%lld%lld",&n,&a)){
if(a&1){
puts("1");
continue;
}
ll mod = 1ll<<n;
ll res = 0;
for(int i=2;i<=n;i+=2)
if(power(a,i,mod) == power(i,a,mod)) res++;
res += (1<<n) >> (up(n,a));
res -= n >> (up(n,a));
printf("%d\n",res);
}
return 0;
}
#10
【bzoj3261】最大異或和
首先,如果是區間異或的話,可以用可持續化Trie樹。對於樹上的可以用dfs序做。查詢就查詢in[u]到out[u]的的區間就行了。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
#define ll long long
#define N 200005
#define inf 2000000000
using namespace std;
inline 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 bin[30];
int n,m;
int a[N],b[N],root[N];
struct trie{
int cnt;
int ch[N*30][2],sum[N*30];
void init(){
cnt = 0;
memset(ch,0,sizeof ch);
memset(sum,0,sizeof sum);
}
int insert(int x,int val){
int tmp,y;tmp=y=++cnt;
for(int i=29;i>=0;i--)
{
ch[y][0]=ch[x][0];ch[y][1]=ch[x][1];
sum[y]=sum[x]+1;
int t=val&bin[i];t>>=i;
x=ch[x][t];
ch[y][t]=++cnt;
y=ch[y][t];
}
sum[y]=sum[x]+1;
return tmp;
}
int query(int l,int r,int val){
int tmp=0;
for(int i=29;i>=0;i--)
{
int t=val&bin[i];t>>=i;
if(sum[ch[r][t^1]]-sum[ch[l][t^1]])
tmp+=bin[i],r=ch[r][t^1],l=ch[l][t^1];
else r=ch[r][t],l=ch[l][t];
}
return tmp;
}
}trie;
int in[N],out[N],cnt;
vector<int> e[N];
void dfs(int id,int fa){
in[id] = ++cnt;
root[cnt] = trie.insert(root[cnt-1],a[id]);
for(auto ep:e[id]){
if(ep == fa) continue;
dfs(ep,id);
}
out[id]=cnt;
}
int main(){
bin[0]=1;for(int i=1;i<=30;i++)bin[i]=bin[i-1]<<1;
while(~scanf("%d%d",&n,&m)){
for(int i=1;i<=n;i++) e[i].clear();
for(int i=1;i<=n;i++)a[i]=read();
for(int i=2;i<=n;i++){
int v;
scanf("%d",&v);
e[v].push_back(i);
}
cnt=0;
trie.init();
dfs(1,0);
int u,x;
//for(int i=1;i<=n;i++){
// printf("in[%d],out[%d] %d\n",in[i],out[i],i);
//}
//cout<<root[4]<<endl;
while(m--){
scanf("%d%d",&u,&x);
printf("%d\n",trie.query(root[in[u]-1],root[out[u]],x));
}
}
return 0;
}
哇哦
相關推薦
2017ACM-ICPC廣西邀請賽-重現賽
這是在厚林工作室4個人打的一場 騷呢 兩年沒回去了 拿lzy的號打,打的被老劉查水錶了 01 列舉kkk^kkk,k≤15k \leq 15k≤15。 看到我的TTT就知道我是怎麼wa的了。。 #include <bits/stdc++.h>
2017ACM/ICPC廣西邀請賽-重現賽(感謝廣西大學) B
Do you like painting? Little D doesn’t like painting, especially messy color paintings. Now Little B is painting. To prevent him fr
HDU 6189 Law of Commutation 2017ACM-ICPC 廣西邀請賽 (打表找規律)
As we all know, operation ''+'' complies with the commutative law. That is, if we arbitrarily select two integers aa and bb, a+ba+b alw
HDU 6185 Covering (2017 廣西邀請賽重現賽)(矩陣快速冪)
題意:用1x2或者2x1的地毯去鋪滿4xN的地面。給定N,問方案數. (偶見DFS暴力搜尋前10個結果,學習中,稍後貼上) 解法:推匯出公式後,轉換成矩陣快速冪求解即可. /*dfs
HDU 5112 A Curious Matt (2014ACM/ICPC亞洲區北京站-重現賽)
mit rds max there span () his acm ans A Curious Matt Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Other
ACM總結——2017ACM-ICPC北京賽區現場賽總結
合並 number 啊啊啊啊啊啊啊啊 greate less striped 模板 strong wine 現在距離比賽結束已經過了一個多星期了,也是終於有時間寫下心得了。回來就是被壓著做項目,也是夠夠的。 這次比賽一樣是我和兩個學弟(雖然是學弟,但我的實力才是最
2016年ACM/ICPC大連賽區重現賽 F題
本題簡單明瞭 給你 T 組資料,然後輸入 n ,把n拆解成不同的數字,使這些數字相乘最大。 。。。 這種簡單題往往最噁心。。 首先我們想一下,如果把一個數拆分成任意的數字相乘,最大的肯定是 2*2*2*2*2*。。。。到最後剩下奇數就*3,但是這道題是不同的數字,就往儘
@2015ACM/ICPC亞洲區長春站-重現賽(感謝東北師大) @HDU5534 (Dp,完全揹包)
題目描述 In mathematics, and more specifically in graph theory, a tree is an undirected graph in which any two nodes are connected by exactly
2016ACM-ICPC廣西邀請賽(三題)
1001 A Math Problem 送分題,問有多少個數 k^k<=n。打表即可。 #include<bits/stdc++.h> using namespace std; long long a[16]={1,1,1,1,1,1,1,1,1,
hdu 6286 ——2018(CCPC2018-湖南全國邀請賽-重現賽(感謝湘潭大學))
2018 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 500 Accepted Submission(
2017ACM-ICPC全國邀請賽(陝西)
沒想到大二下學期又能有幸的參加一場全國邀請賽,跟各位大佬齊聚一堂享受被虐的快感。 =========================日常水========================== 弱校抱著拿區域賽拿名額的心態來打了這場比賽,前幾場比賽沒打
2017ACM/ICPC亞洲區瀋陽站-重現賽(感謝東北大學)
Little Boxes Problem Description Little boxes on the hillside. Little boxes made of ticky-tacky. Little boxes. Little boxes. Little boxes all
計蒜客17119TrigFunction數學2017ACM-ICPC亞洲區(西安賽區)網絡賽
zju 網絡 umt lrn vcf ios sina udid log l7ebq7叫扛笛承睬悠http://shufang.docin.com/iwl603ioss8n舜源首掖短指http://huiyi.docin.com/sina_62699824234joh1x俁
HDU 5512 Pagodas(2015ACM/ICPC亞洲區瀋陽站-重現賽(感謝東北大學))
Pagodas Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 3502 &nb
hihocoder 1873 ACM-ICPC北京賽區2018重現賽 D Frog and Portal
http://hihocoder.com/problemset/problem/1873 時間限制:1000ms 單點時限:1000ms 記憶體限制:512MB 描述 A small frog wants to get to the other s
2016ACM/ICPC亞洲區大連站-重現賽 d
首先這道題需要理解一個概念 就是 若 i,j 互質 ,則 i+j 和 i*j 互質 證明如下:(感謝隊友的思路) 如果 i j 互質, i+j 和 i*j 不互質,那麼 i+j 和
2016ACM/ICPC亞洲區大連站-重現賽 A
題目大意: 已知有n個人,他們進行了m場比賽,已知其中有X個好人,Y個壞人。比賽一定是在好人和壞人之間進行的。問是否能夠把n個人劃分成好人和壞人兩個部分 好人和中立人打 中立人變成壞人,壞人和中立人打 中立人變成好人 做的時候開始發現就是一個二分圖,開始不知道
2016ACM/ICPC亞洲區大連站-重現賽 B
題目如下 給你一個長度為 n 的字串,之後 n 行每行輸入 a 然後輸入 a 個 ai 代表 字串的第 i 位可以為 a0-----aa。 最後輸入主串,問主串中包含了多少個可行的字串,輸出字串。 字串判斷題。。開始想用 kmp 但是發現 沒有重複性的話就會超時。。
2016ACM/ICPC亞洲區大連站-重現賽 E
讀題真的費了點時間,但是讀懂後就發現並不是那麼困難。 這道題很簡單明瞭。。題幹裡說的什麼集合看起來很高階。。但是你仔細拆解一下就會發現。。這個就是樹狀陣列。。 問題就是 n m ,代表 n 個元素,m個詢問。每次詢問有兩種 1.詢問區間 a b 之間 lowbit
2015ACM/ICPC亞洲區瀋陽站---重現賽感想
今天打的差極了,,就A了兩個題,,今早九點開始,還真是有點困困的、、今天來的還有點晚。 先看的BD題,兩題並行,然後先敲的B,未果,D替代紙上完成。然後敲了D題,,A了之後就在做B和M,我先做的M,果然存圖沒想到,,然後就亂交了一發,,想象的T,結果RE了,,,遂放棄。