第四天——数据结构2

今天上数据结构2。好吧我基本没听懂。so我今天不可避免的再次爆零了。但真的好难啊。好吧,今天题是:

1:有n个元素,都为0。

  0 开头是做反操作。 1开头是找有多少个1;

 我觉得还是挺简单的,但看到数据大小我呵呵了。n,m<=100000;呵呵

#include <bits/stdc++.h>
using namespace std;
int n, m;
struct Node {
int sum , tag , l , r;
Node() {
sum = 0;
tag = 0;
}
}t[1000010];


int query(int now, int l, int r) {
if (l <= t[now].l && r >= t[now].r)
return t[now].sum;
int mid = (t[now].l + t[now].r) >> 1;
if (t[now].tag) {
t[now].tag = 0;


if (t[now * 2].l != 0) {
t[now * 2].sum = t[now * 2].r - t[now * 2].l + 1 - t[now * 2].sum;
t[now * 2].tag = !t[now * 2].tag;
}


if (t[now * 2 + 1].l != 0) {
t[now * 2 + 1].sum = t[now * 2 + 1].r - t[now * 2 + 1].l + 1 - t[now * 2 + 1].sum;
t[now * 2 + 1].tag = !t[now * 2 + 1].tag;
}
}
if (r <= mid)return query(now * 2, l, r);
else if (l >= mid + 1)return query(now * 2 + 1, l, r);
else return query(now * 2, l, mid) + query(now * 2 + 1, mid + 1, r);
}


void modify(int now, int l, int r) {
if (l <= t[now].l && r >= t[now].r) {
t[now].sum = t[now].r - t[now].l + 1 - t[now].sum;
t[now].tag = !t[now].tag;
return;
}
int mid = (t[now].l + t[now].r) >> 1;
if (t[now].tag) {
t[now].tag = 0;
if (t[now * 2].l != 0) {
t[now * 2].sum = t[now * 2].r - t[now * 2].l + 1 - t[now * 2].sum;
t[now * 2].tag = !t[now * 2].tag;
}


if (t[now * 2 + 1].l != 0) {
t[now * 2 + 1].sum = t[now * 2 + 1].r - t[now * 2 + 1].l + 1 - t[now * 2 + 1].sum;
t[now * 2 + 1].tag = !t[now * 2 + 1].tag;
}
}
if (r <= mid) {
modify(now * 2, l, r);
}
else if (l >= mid + 1) {
modify(now * 2 + 1, l, r);
}
else {
modify(now * 2, l, mid);
modify(now * 2 + 1, mid + 1, r);
}
t[now].sum = t[now * 2].sum + t[now * 2 + 1].sum;
}


void build(int now, int l, int r) {
if (r < l)return;
if (l == r) {
t[now].l = t[now].r = l;
return;
}
t[now].l = l;
t[now].r = r;
int mid = (t[now].l + t[now].r) >> 1;
build(now * 2, l, mid);
build(now * 2 + 1, mid + 1, r);
}


int main() {
freopen("seq.in", "r", stdin);
freopen("seq.out", "w", stdout);
cin >> n >> m;
int x, y, c;
build(1 , 1 , n);
for (int i = 1; i <= m; ++i) {
//cin >> c >> x >> y;
scanf("%d%d%d" , &c , &x , &y);
if (c) {
cout << query(1, x, y) << endl;
}
else {
modify(1, x, y);
}
}
fclose(stdin);fclose(stdout);
return 0;

}

OK。

2:有n个任务,有任务结束时间d,获利值p。每个任务需1个时刻做。

     好吧,题面还是挺简单的,但是还是数据大小n<=100000,1<=p,d<=1000000000;呵呵我又笑了。

     #include<bits/stdc++.h>
using namespace std;
struct task{
int d, p;
}d[100010];
bool cmp(task a,task b){
return a.d < b.d;
}
priority_queue<int>q;
int main(){
freopen("ddl.in" , "r" , stdin);freopen("ddl.out" , "w" , stdout);
int n , cnt = 0;
long long ans = 0;
scanf("%d" , &n);
for (int i = 1 ; i <= n ; ++i)
scanf("%d%d" , &d[i].d , &d[i].p);
sort(d + 1 , d + n + 1 , cmp);
for (int i = 1 ; i <= n ; ++i){
ans += d[i].p;
++cnt;
q.push(-d[i].p);
if(d[i].d < cnt){
--cnt;
ans += q.top();
      q.pop();
}
}
cout<<ans<<endl;
fclose(stdin);fclose(stdout);
return 0;
}  

ok.

3:嫌疑人说真假话

#include <bits/stdc++.h>
using namespace std;
int n, m;
int f[2010] = {};
int getfather(int x) {
if (x == f[x])return x;
return f[x] = getfather(f[x]);
}
int main() {
freopen("truth.in" , "r" , stdin);
freopen("truth.out" , "w" , stdout);
cin >> n >> m;
char c; int x, y, fx, fy , ffx , ffy;
for (int i = 1; i <= 2 * n; ++i)f[i] = i;
int i;
for (i = 1; i <= m; ++i) {
cin >> x >> y >> c;
fx = getfather(x);
fy = getfather(y);
ffx = getfather(x + n); //对立面
ffy = getfather(y + n); //对立面

if (c == 'L') {
if (fx == fy || ffx == ffy)break;
f[fx] = ffy;
f[ffx] = fy;
}
else {
if (fx == ffy || ffx == fy)break;
f[fx] = fy;
f[ffx] = ffy;
}
}
cout << i - 1 << endl;
fclose(stdin);fclose(stdout);

}

OK;

4:拍毕业照排队,有n人,只能和左右人交换。所以

#include <bits/stdc++.h>
using namespace std;
int N, c[100010] = {}, p[100010] = {}, S[100010] = {};

bool cmp(int pa, int pb) 

{

return c[pa] < c[pb];
}

inline int lowbit(int n)

 {

return n & (-n);
}

int sum(int n)

 {

int ret = 0;
while (n>0) {
ret += S[n];
n -= lowbit(n);
}
return ret;
}

void modify(int n, int delta)

 {

while (n <= N) {
S[n] += delta;
n += lowbit(n);
}
}

int main()

 {

freopen("photo.in", "r", stdin);
freopen("photo.out", "w", stdout);
cin >> N;
for (int i = 1; i <= N; ++i) {
cin >> c[i];
p[i] = i;
S[i] = 0;
}
sort(p + 1, p + N + 1, cmp);
for (int i = 1; i <= N; ++i)c[p[i]] = i;
long long ans = 0;
for (int i = N; i >= 1; --i) {
ans = ans + (long long)sum(c[i] - 1);
modify(c[i], 1);
}
cout << ans << endl;
fclose(stdin);fclose(stdout);
return 0;

}

OK

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值