a. hdu 6230
乙個合法的子串(s = 3n - 2)滿足條件即1-2n-1 為以n為回文中心的回文串,n-3n-2為以2n-1為中心的回文串。故我們可以通過尋找回文中心對,來判斷相應合法子串的個數。利用manacher求出每個位置的最長回文半徑,則若i,j滿足條件(i < j) ,則應有 \(p[i] \geqslant j - i + 1\), \(p[j] \geqslant j - i + 1\)。變換一下有 \(j \leqslant p[i] + i + 1\),\(j - p[j] + 1 \geqslant i < j\)。所以掃瞄第一維,然後樹狀陣列區間查詢第二維即可。
#include usingnamespace
std;
#define maxn 1000000
#define int long long
#define lowbit(i) (i & (-i))
intn, ans, c[maxn], pld[maxn];
char
s[maxn];
intread()
while(c >= '
0' && c <= '
9') x = x * 10 + c - '
0', c =getchar();
return x *k;
}struct
node
}b[maxn];
void add(int x, int
y) int que(int
x) void
manacher()
else pld[i] = 1
;
int r = min(n - i, i - 1
);
while(pld[i] <= r && s[i + pld[i]] == s[i - pld[i]]) pld[i] ++;
if(i + pld[i] - 1 > mx) mx = i + pld[i] - 1, id =i;
}}signed main()
printf(
"%lld\n
", ans);
}return0;
}
b.hdu 6231
二分答案。設二分的答案為mid,則考慮統計第k大數大於等於mid的區間共有多少個。把所有大於等於mid的數看做有效數字,等價於統計其中含有至少k個有效數字的區間的個數。若此時區間個數少於s,說明答案應當減小。若大於等於,則增大答案繼續尋找。
#include usingnamespace
std;
#define maxn 200000
#define int long long
#define inf 2000000000ll
intn, k, m, a[maxn], b[maxn], sum[maxn];
intread()
while(c >= '
0' && c <= '
9') x = x * 10 + c - '
0', c =getchar();
return x *k;
}bool check(int
mid)
return ans }signed main()
printf(
"%lld\n
", l);
}return0;
}
f. hdu6235
簽到題。
#include usingnamespace
std;
#define maxn 200000
#define int long long
#define inf 2000000000ll
intn, k, m, a[maxn], b[maxn], sum[maxn];
intread()
while(c >= '
0' && c <= '
9') x = x * 10 + c - '
0', c =getchar();
return x *k;
}bool check(int
mid)
return ans }signed main()
printf(
"%lld\n
", l);
}return0;
}
h.hdu6237
首先發現最後的x一定是石子總個數的質因子之一,而質因子總數最多不超過20。列舉每乙個質因子,將石堆石子個數對 x 取模。之後排序,最優方案一定是把模意義下個數小的石堆的石子往模意義下個數大的石堆上挪。
#include usingnamespace
std;
#define maxn 500000
#define maxn 500000
#define inf 99999999999999ll
#define ll long long
#define int long long
intn, tot, cnt, p[maxn], pri[maxn], a[maxn], b[maxn];
ll sum, ans;
bool
is_pri[maxn];
intread()
while(c >= '
0' && c <= '
9') x = x * 10 + c - '
0', c =getchar();
return x *k;
}void
get_prime()
}}bool
check(ll x)
ll solve(
intp) }}
returnw;}
signed main()
if(check(sum)) p[++ cnt] =sum;
for(int i = 1; i <= cnt; i ++)
printf(
"%lld\n
", ans);
}return0;
}
l.hdu6241
第乙個條件子樹中至少塗幾個點,第二個條件子樹外至少塗幾個點。二分答案後,這兩個條件轉化為子樹內至少塗幾個點,至多塗幾個點。樹形向上整合區間取交,判斷是否出現空集。
#include usingnamespace
std;
#define maxn 500000
intn, mid, num[maxn], dp[maxn], size[maxn], a[maxn], b[maxn];
intl[maxn], r[maxn];
bool
flag;
intread()
while(c >= '
0' && c <= '
9') x = x * 10 + c - '
0', c =getchar();
return x *k;
}struct
edge
}e;void dfs(int u, int
fa)
}void dp(int u, int
fa)
r[u] = min(r[u], mid -b[u]);
l[u] =max(l[u], a[u]);
if(l[u] > r[u] || n - size[u] < b[u]) flag = 0;}
bool check(int
mid)
intmain()
int a =read();
for(int i = 1; i <= a; i ++)
int b =read();
for(int i = 1; i <= b; i ++)
dfs(
1, 0
);
int l = 1, r =n;
while(l if(check(0)) printf("
0\n"
);
else
if(check(l)) printf("
%d\n
", l);
else printf("
-1\n");
}return0;
}
m.hdu6242
三點確定乙個圓,由於有一半的點都在乙個圓上,因此每次隨機三個點找到圓的概率很高。
【一直tle | wa】咕咕咕
訓練賽 詠歎
安師大附中訓練題目 給定乙個1到n的排列a,對其進行氣泡排序 counter 0 while a不是公升序的 counter counter 1 for i 1 to n 1 if a i a i 1 then swap a i a i 1 endifend forend while那麼經過幾輪排序...
訓練賽 浣熊
從前有乙隻可愛的小浣熊居住在美麗的森林裡。他聽說小鸚鵡要旅行到另乙隻鸚鵡家做客,也想邀請朋友們來自己家。為此,小浣熊想建一棟新房子。他找到了一塊比較大的平地,不過這塊地上還是有一些地方不能建屋。不妨把這塊空地看作是由n行m列等大小的正方形格仔組成。現在,小熊已經把不能建房子的地方都標記了出來,他想找...
訓練賽補題
codeforces 1041b 思考 1 求最大公約數的時候除法比減法要快,以後能用除法去處理大數就不要用劍法去處理大數 codeforces 1041c 題意 其實就是給定了n個數,問間隔最少d,那麼這樣最少是幾組,並且哪個是哪一組的 思路 就是直接進行比較,先進行按照數值進行從小到大排序,如果...