HDU 5358 First One(枚举)
来源:互联网 发布:苹果mac如何收藏网页 编辑:程序博客网 时间:2024/05/23 10:55
这道题如果按照表达式一个个来算肯定超时,下午时候想了一个O(nlogn*logn)的算法,但是t了,因为这道题卡的非常紧几百个样例,必须nlogn的算法才可以ac
回到这道题,考虑log(sum(i,j))+1的特点,可以发现它的值域范围非常小,在1-34之间,那么我们可以考虑枚举log(sum(i,j)+1的值,记为k,然后统计(i+j)的和即可。
对于每一个k,找到所有满足2^(k-1)<=sum(i,j)<=2^k-1的(i+j),
那么我们考虑每个前缀i,找到这个前缀满足2^(k-1)<=sum(i,j)<=2^k-1的区间[l,r],即对于这个区间的每个元素s(i,j),都满足上式(l<=j<=r)。
这一步枚举有一个小技巧,当我们找到前缀i的区间[l,r]之后,那么前缀i+1满足上式的区间一定不可能在前缀i的[l, r]之前。
那么我们用两个指针维护这个区间即可,那么时间复杂度就降为了O(n*logn).
ps:下午写的n*logn*logn的代码在我电脑上跑了22000ms,ac代码在我电脑上跑了5500ms,ac代码在oj上跑了1600ms。
#include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<queue> #include<stack> #include<string>#include<ctime> #include<map> #include<set>#define eps 1e-6 #define LL long long #define pii (pair<int, int>)//#pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; const int maxn = 100000 + 500;//const int INF = 0x3f3f3f3f;LL a[maxn], s[maxn];int n;int main() {clock_t start = clock();//freopen("input.txt", "r", stdin);int T; cin >> T;while(T--) {scanf("%d", &n);LL ans = 0;for(int i = 1; i <= n; i++) {scanf("%I64d", &a[i]);s[i] = s[i-1] + a[i];}for(int k = 1; k <= 34; k++) {int l = 1, r = 0;LL liml = k==1 ? 0 : (1LL<<(k-1)), limr = (1LL<<k)-1;for(int i = 1; i <= n; i++) {l = max(i, l);while(l<=n && s[l]-s[i-1]<liml) l++;r = max(l-1, r);while(r+1<=n && s[r+1]-s[i-1]>=liml && s[r+1]-s[i-1]<=limr) r++;if(l>r) continue;//if(k==2) cout << l << " " << r << " " << i << endl;ans += (LL)(i+l+i+r)*(r-l+1)/2*k;}//if(k < 5) cout << ans << endl;}cout << ans << endl;}clock_t end = clock();//cout << end-start << endl;return 0;}
1 0
- HDU 5358 First One(枚举)
- HDU 5358 First One(枚举)
- HDU 5358 First One(枚举+尺举法)
- hdu 5358 First One [枚举+尺取法]
- 多校第六场 1006 hdu 5358 First One(枚举)
- HDU 5358 First One
- HDU 5358 First One
- HDU 5358 First One
- 【瞎搞】 HDU 5358 First One
- hdu 5358 First One 数学
- hdu 5358 First One 2015多校联合训练赛#6 枚举
- HDU 5358 多校第6场 First One
- hdu 5358 First One(想法题)
- hdu 5358 First One(二进制+twopoint)
- hdu 5358 First One (尺取法)
- HDU 5358 First One(尺取法)
- HDU 5358 First One 数学+尺取法
- 数学题(First One,HDU 5358)
- cocos2d-x的android项目中如何加载第三方so库
- 【小熊刷题】valid palindrome
- Sprite 3D用法和相关特性详解(包括如何从零到一个完整工程)
- std::function与std::bind 函数指针
- C++中friend的使用(friend function and friend class)
- HDU 5358 First One(枚举)
- std::thread and std::mutex
- Java和Javascript对比
- C++ Virtual详解
- std::string用法总结
- Cocos2d-x-3.6 用户交互原理---------如何通过JNI连接Java和C++
- cocos2dx导入到eclipse出现"C/C++ Indexer". java.lang.NullPointerException
- CocosDeshion's android.mk 文件的理解
- Cocos2d-X权威指南笔记