t1輸出0有20分結果我輸出1爆0(題目說精度差為整數有40%的分數,結果告訴我只能差0.5……),t2打了20分暴力,t3交了個感覺能拿50分的結果是正解……被卡常了乙個點,總分110/300
t1.圓
計算幾何,正解好像是什麼什麼積分,什麼什麼掃瞄線,什麼什麼公式,不管了,以後有機會再說
t2.方
題目大意:乙個n*m的01矩陣,q個操作,每次修改矩陣中乙個元素,並詢問最大的全是0的正方形的邊長。(n*m<=4,000,000,q<=3,900)
思路:如果列多於行我們轉置矩陣,然後用線段樹維護行,線段樹中每個節點維護對應的行區間中每列上方有多少連續的0,下方有多少連續的0,每次合併資訊時利用這些資訊計算行區間內的答案,每次為左右兒子的答案與過中線的答案的最大值,計算過中線答案的方法如下:從左到右用兩個單調佇列維護上半行區間下方連續0的數量和下半行區間上方連續0的數量單調遞增,用左右兩個指標表示當前考慮的正方形的左右端點,每次把右指標所在的列加入佇列,並考慮若右指標到左指標的距離超過左指標所在列的上下寬度,說明此時左指標應向右移動,重複這樣既可統計出答案,更具體的實現可參見下面的**,這樣每次更新是o(min(n,m))的,總複雜度o(nm+qmin(n,m)logmax(n,m))。
#include#includeusing
namespace
std;
inline
intread()
inline
intget()
#define mn 2000
#define mm 4000000
#define l k<<1
#define r k<<1|1
int m,*a[mm+5],qx[mn+5],qxl,qxr,qy[mn+5
],qyl,qyr;
struct nodet[mm*4+5
];void up(intk)}
void init(int k,int
x)void build(int k,int l,int
r)
int mid=l+r>>1
; build(l,l,mid);build(r,mid+1
,r);up(k);
}void renew(int k,int x,int
y) renew(x>t[k].l+t[k].r>>1?r:l,x,y);up(k);
}int
main()
fclose(stdin);fclose(stdout);
return0;
}
t3.樹
題目大意:給出一棵n個節點的樹,每個節點可以染成黑色或白色,給出b條黑鏈和w條白鏈,若黑鏈上的點全被染成黑色,則可獲得該條鏈對應的權值,白鏈同理,求最大收益。(n<=100,000,b,w<=30,000)
#include#include#include
using
namespace
std;
char b[1
<<26],*s=b,c;int
x;inline
intread()
#define mn 100000
struct tedgete[mn*2+5
];int th[mn+5],ten,fa[mn+5],f[mn+5],s[mn+5],mx[mn+5],l[mn+5],cnt,dep[mn+5
];inline
void tins(int x,int
y);th[x]=ten;
te[++ten]=(tedge);th[y]=ten;
}void pre(intx)}
void work(int x,int
k)#define mv 860000
#define me 10000000
#define s mv+1
#define t mv+2
#define inf 0x7fffffff
struct nodet[mn*4+5
];struct edgee[me*2+5
];int h[mv+5],en=1,d[mv+5],q[mv+5],qn,c[mv+5
];inline
void ins(int x,int y,int
w);h[x]=en;
e[++en]=(edge);h[y]=en;
}void build(int k,int l,int
r)void insb(int k,int l,int r,int
p)
int mid=t[k].l+t[k].r>>1
;
if(r<=mid)insb(k<<1
,l,r,p);
else
if(l>mid)insb(k<<1|1
,l,r,p);
else insb(k<<1,l,mid,p),insb(k<<1|1,mid+1
,r,p);
}void insw(int k,int l,int r,int
p)
int mid=t[k].l+t[k].r>>1
;
if(r<=mid)insw(k<<1
,l,r,p);
else
if(l>mid)insw(k<<1|1
,l,r,p);
else insw(k<<1,l,mid,p),insw(k<<1|1,mid+1
,r,p);
}void buildb(int k,int x,int
y)void buildw(int k,int x,int
y)bool
bfs()
int dfs(int x,int
r)
return d[x]=0
,u;}
intmain()
四校聯考 20171001
二分 期望得分 70 實際得分 10 列舉最高的高度可能為多少 二分。o logm 列舉最高高度應該位於哪一列上.o n 左右擴散列舉出需要用的積木總數,與m相比較。容易發現合法的高度的最高值,最終需要搭建乙個金字塔。1,3,5,7 正解是預處理出每一列作為最高列的左右邊界。然後再二分最大高度。ch...
四校聯考(20170910)
ditoly出的題目果然喪,待我一天啃一題。廢話不多說,開更 我是分割線 t1 最大值 max 問題描述 小c有n個區間,其中第i個區間為 li,ri 小c想從每個區間中各選出乙個整數,使得所有選出的數and起來得到的結果最大,請你求出這個值。輸入格式 第一行乙個正整數n,表示區間個數。接下來n行,...
四校聯考 傳遞
題解 如果乙個圖是競賽圖那麼如果存在邊,那麼a一定能走到b,反之亦然 還有,如果在圖p中存在邊,那麼圖q中一定不存在邊或 基圖是完全圖 那麼,如果圖p中存在邊,圖q一定不能從a走到b或者從b走到a 既然如此,因為圖p 圖q是完全圖 所以,對於點u和點v,u和v之間的邊要不然在p裡,要不然在q裡,所以...