CSP模擬 模擬測試5

2022-03-24 18:43:53 字數 3901 閱讀 4599

題意是讓求平均值第k小的連續子區間。

發現直接計算無論怎麼優化都是 \(n^2\) 的,然後發現這樣找k個的似乎可以考慮二分答案。

簡單推一下式子。

記 \(sum[i]\) 為字首和,顯然符合條件的區間有:

\[\frac \leq mid\]即

\[sum[j] - j \times mid \leq sum[i] - i\times mid

\]預設 \(j < i\),區間為 \([i+1,j]\),所以顯然下標從0開始。

所以問題轉化為乙個類似01分數規劃的東西,check的話用樹狀陣列求逆序對,注意處理下標為0。

**寫得有點長,而且沒有卡常所以有點慢。

#include #include #include #include using namespace std;

const int maxn = 1e5 + 10;

const double eps = 1e-8;

double sum[maxn];

int w[maxn];

long long n, k;

void add(int i, int val)

int ask(int i)

struct node tmp[maxn];

bool cmp(node x, node y)

bool check(double mid) ;

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

tmp[i] = (node) ;

sort(tmp, tmp + 1 + n, cmp);

for (int i = n; i >= 0; i--)

for (int i = 0; i <= n; i++) add(i + 1, -1);

return cnt >= k;

}int main()

double l = 1.0, r = 1000000000.0, mid;

while (r - l > eps) ^} \times \sum_^c_^c_^\)

\(f[i][j]=f[i-1][k] \times h[k][j]\)

發現\(f\)的轉移跟\(i\)無關,再加上\(m\)如此巨大,可以矩陣乘。

其實並不用真正寫乙個矩陣快速冪,但我還是無腦套了板子...

另外,注意卡常。

#include #include #include #include using namespace std;

const int maxn = 105;

const int mo = 998244353;

int n, m, p, q;

long long g[maxn][maxn], h[maxn][maxn], c[maxn][maxn];

struct mat

void init()

} }

mat operator * (const mat &b) const

c.w[i][j] %= mo;

}} return c;

}};long long qpow(long long x, int t)

return s;

}mat matpow(mat x, int t)

return s;

}int main()

}for (register int j = 1; j <= n; j++)

}mat base, ans;

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

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

base.w[i][j] = h[i][j];

for (int i = 1; i <= min(p, n); i++)

base = matpow(base, m - 1);

ans = ans * base;

long long sum = 0;

for (int i = 1; i <= min(n, p); i++)

sum = (sum + ans.w[1][i]) % mo;

cout << sum << endl;

return 0;

}

考場上打了1h+的主席樹掛了...

用線段樹套vector水過。

每個節點開乙個vector,存下能夠完全覆蓋此節點代表區間的詢問的x值。(注意保證vector有序)

然後考慮每個a[i]的貢獻,從根一直到區間為i的葉子節點,每到乙個節點就在該節點的vector裡二分一下,由於乙個詢問最多隻會更新乙個節點一次,所以貢獻不會算重。

ans[i]記錄a[i]的貢獻。

修改的話直接計算更新即可。

#include #include #include #include #include using namespace std;

const int maxn = 1e5 + 10;

inline int read()

while (c >= '0' && c <= '9') s = s * 10 + c - '0', c = getchar();

return s * w;

}struct tree t[maxn << 2];

#define ls (u << 1)

#define rs (u << 1 | 1)

void update(int u, int l, int r, int ql, int qr, int val)

int mid = (l + r) >> 1;

if (ql <= mid) update(ls, l, mid, ql, qr, val);

if (qr > mid) update(rs, mid + 1, r, ql, qr, val);

return;

}int get(int u, int val)

}if (flag) ans = t[u].qe.size();*/

int l = 0, r = t[u].qe.size() - 1, mid;

while (l <= r)

//cout << "************" << endl;

//printf("ans = %d l = %d\n", ans, l);

//cout << "************" << endl;

return l;

}int ask(int u, int l, int r, int pos, int val)

int mid = (l + r) >> 1;

int ans = 0;

ans += get(u, val);

if (pos <= mid) ans += ask(ls, l, mid, pos, val);

else ans += ask(rs, mid + 1, r, pos, val);

return ans;

}int n, m, q;

int a[maxn];

int aa[maxn];

struct node qq[maxn];

bool cmp(node aa, node bb)

int main()

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

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

int ans = 0;

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

printf("%d\n", ans);

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

//cout << aa[i] << endl;

int u, v, pos, val;

while (q--)

}

csp模擬 模擬測試16

fdasds include using namespace std define cle a memset a,0,sizeof a inline int read const int mod 1e9 7,maxn 1e3 100 int n,m,ans 0 int f maxn maxn int...

csp模擬 模擬測試4

t1是暴力分,t2當時沒有花太多時間去推導,一見到t2就十分害怕,便放過了它,t3的話花了大量的時間推了乙個錯誤的解,以後對於t2這種題不要未戰先怯,一點一點的去推導!那一天我們在教室裡許下約定。我至今還記得我們許下約定時的歡聲笑語。我記得她說過她喜歡吃餅乾,很在意自己體重的同時又控制不住自己。她跟...

CSP2019模擬測試 遊戲

給定乙個n m n mn m的矩形方格紙,每次可以把它裁為兩個子矩形,若裁出乙個1 1 1 11 1則勝,判斷先手是否必勝。n 2000,m 2000 n le 2000,m le 2000 n 2000 m 2 000 直觀的想法是設f i j f i j f i j 為i ji j i j的矩形...