Wanafly 練習賽8 題解

2021-08-14 06:56:13 字數 3069 閱讀 1125

a:給個n,求1到n的所有數的約數個數的和~

解法:列舉每個可能的約數,然後答案就是對n/i求和。。這個直接列舉會t,然後發現這個可以分塊求。。

#include using namespace std;

typedef long long ll;

ll n;

//sinma(n/i)

int main()

return 0*printf("%lld\n", ans);

}

d:給你乙個 

n 個點,

m 條邊的無向圖,求至少要在這個的基礎上加多少條無向邊使得任意兩個點可達

~ 解法:答案就是連通塊個數減一,dfs或者並查集

#include using namespace std;

const int maxn = 100010;

int n,m,fa[maxn];

int find_set(int x)

void union_set(int x,int y)

}bool vis[maxn];

int main()

for(int i=1;i<=n;i++)

}return 0*printf("%d\n", ans-1);

}

b:乙個數軸,每乙個儲物點會有一些東西,同時它們之間存在距離。

每次給個區間[l,r],查詢把這個區間內所有儲物點的東西運到另外乙個儲物點的代價是多少?

比如儲物點i有x個東西,要運到儲物點j,代價為x * dist( i , j )

dist就是儲物點間的距離。 

解法:維護幾個字首和即可啦。

#include using namespace std;

typedef long long ll;

const int mod = 1000000007;

const int maxn = 200010;

int n,m;

ll a[maxn],b[maxn];

ll sum1[maxn], sum2[maxn], sum3[maxn];

ll cal(int x, int l, int r)

else

}int main()

ok^=1;}}

if(jud==0) continue;

if(ok)

ans-=m/temp;

else

ans+=m/temp;

}return 0*printf("%lld\n", ans);

}

f:給乙個長為 n 的只含小寫字母的字串

每次查詢乙個區間 [l,r] 內,有多少子區間可以重排為乙個回文串

解法:

考慮乙個區間可以重排為回文串,即其中最多只有乙個字元出現奇數次

把』a』 -> 1 , 『b』 -> 2 , 『c』 -> 4 ... 『z』 -> 2^25

這樣等價於這個區間的xor和為

2的整次冪

我們維護乙個字首xor和

bi = a1 ^ a2 ^ ... ^ ai

,然後等價於查詢區間

[l,r]

中有多少點對

(x,y)

滿足b[x-1]^b[y]為2

的整次冪

這個明顯可以莫隊維護,複雜度o( 27nsqrt( n ) )

#include using namespace std;

const int maxn = 60010;

typedef long long ll;

int n, m, block;

int tot;

char str[maxn];

map mp;

ll ans[maxn], sum;

vector v[maxn];

struct node

q[maxn];

int s[maxn * 27], presum[maxn];

bool cmp(const node&a, const node &b)

inline int rd()

while(gc>='0'&&gc<='9') ret=ret*10+(gc^'0'),gc=getchar();

return ret*f;

}int main()

if (mp.find(presum[i])==mp.end()) mp[presum[i]] = ++tot;

v[i].push_back(mp[presum[i]]);

}for (int i = 0; i <= n; i++)

}for (int i = 1; i <= m; i++) q[i].l = rd(), q[i].r = rd() , q[i].l--, q[i].id = i;

sort(q + 1, q + m + 1, cmp);

int l = 1, r = 0;

vector ::iterator it;

for (int i = 1; i <= m; i++)

for (; r < q[i].r; s[v[r][0]]++)

for (; l < q[i].l; l++)

for (; r > q[i].r; r--)

ans[q[i].id] = sum;

}for (int i = 1; i <= m; i++) printf("%lld\n", ans[i]);

}

c:不會。

題意:給乙個長為 n 的只含小寫字母的字串

設總共有 x 個回文連續子串

在這 x 個子串中任選不同的兩個,有公共部分的方案數

答案對 1000000007 取模

解法:

考慮容斥一下,求兩個不相交的回文子串很好求

列舉一下分割線,然後嚴格屬於兩邊的回文子串就可以產生貢獻

大力差分一下,維護兩個字首和,算算貢獻就可以了

o( n )

沒看懂這個怎麼算的。。誰知道可以教教我啊。。

10 5號新生練習賽題解

第一題 hdu 2022 include include include include 包含abs函式的函式庫 using namespace std 命名空間 解釋下abs函式,abs函式是取絕對值的函式 int main int r 1,c 1,ma abs a 1 1 r代表分數絕對值最大的...

牛客練習賽22題解

簡單瞎搞題 不會用bitset,所以沒做出來。實際上還是比較簡單的。include using namespace std bitset 1000005 dp 2 int main cout 2 count 簡單資料結構1 這裡要運用拓展尤拉定理。ab modp ab p b p p 0 modp ...

題解 牛客練習賽51

字首a的數量,字尾c的數量,遇到b就計算一次答案。includeusing namespace std typedef long long ll const int n 1e5 100 char s n int cnt n int main int tmp 0 for int i 1 i n i p...